1/*
2 * libjingle
3 * Copyright 2008 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "webrtc/base/arraysize.h"
29#include "webrtc/base/byteorder.h"
30#include "webrtc/base/gunit.h"
31#include "webrtc/call.h"
32#include "talk/media/base/constants.h"
33#include "talk/media/base/fakemediaengine.h"
34#include "talk/media/base/fakenetworkinterface.h"
35#include "talk/media/base/fakertp.h"
36#include "talk/media/webrtc/fakewebrtccall.h"
37#include "talk/media/webrtc/fakewebrtcvoiceengine.h"
38#include "talk/media/webrtc/webrtcvoiceengine.h"
39#include "webrtc/p2p/base/faketransportcontroller.h"
40#include "talk/session/media/channel.h"
41
42using cricket::kRtpAudioLevelHeaderExtension;
43using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
44
45namespace {
46
47const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
49const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
50const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
51const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
52const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
53const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
54const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
55const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0,
56                                               1, 0);
57const uint32_t kSsrc1 = 0x99;
58const uint32_t kSsrc2 = 0x98;
59const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
60
61class FakeVoEWrapper : public cricket::VoEWrapper {
62 public:
63  explicit FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine* engine)
64      : cricket::VoEWrapper(engine,  // processing
65                            engine,  // base
66                            engine,  // codec
67                            engine,  // hw
68                            engine,  // network
69                            engine,  // rtp
70                            engine) {  // volume
71  }
72};
73}  // namespace
74
75class WebRtcVoiceEngineTestFake : public testing::Test {
76 public:
77  WebRtcVoiceEngineTestFake()
78      : call_(webrtc::Call::Config()),
79        engine_(new FakeVoEWrapper(&voe_)),
80        channel_(nullptr) {
81    send_parameters_.codecs.push_back(kPcmuCodec);
82    recv_parameters_.codecs.push_back(kPcmuCodec);
83  }
84  bool SetupEngine() {
85    if (!engine_.Init(rtc::Thread::Current())) {
86      return false;
87    }
88    channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
89    return (channel_ != nullptr);
90  }
91  bool SetupEngineWithRecvStream() {
92    if (!SetupEngine()) {
93      return false;
94    }
95    return channel_->AddRecvStream(
96        cricket::StreamParams::CreateLegacy(kSsrc1));
97  }
98  bool SetupEngineWithSendStream() {
99    if (!SetupEngine()) {
100      return false;
101    }
102    return channel_->AddSendStream(
103        cricket::StreamParams::CreateLegacy(kSsrc1));
104  }
105  void SetupForMultiSendStream() {
106    EXPECT_TRUE(SetupEngineWithSendStream());
107    // Remove stream added in Setup.
108    EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
109    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc1));
110    // Verify the channel does not exist.
111    EXPECT_FALSE(call_.GetAudioSendStream(kSsrc1));
112  }
113  void DeliverPacket(const void* data, int len) {
114    rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len);
115    channel_->OnPacketReceived(&packet, rtc::PacketTime());
116  }
117  void TearDown() override {
118    delete channel_;
119    engine_.Terminate();
120  }
121
122  const cricket::FakeAudioSendStream& GetSendStream(uint32_t ssrc) {
123    const auto* send_stream = call_.GetAudioSendStream(ssrc);
124    EXPECT_TRUE(send_stream);
125    return *send_stream;
126  }
127
128  const webrtc::AudioSendStream::Config& GetSendStreamConfig(uint32_t ssrc) {
129    const auto* send_stream = call_.GetAudioSendStream(ssrc);
130    EXPECT_TRUE(send_stream);
131    return send_stream->GetConfig();
132  }
133
134  const webrtc::AudioReceiveStream::Config& GetRecvStreamConfig(uint32_t ssrc) {
135    const auto* recv_stream = call_.GetAudioReceiveStream(ssrc);
136    EXPECT_TRUE(recv_stream);
137    return recv_stream->GetConfig();
138  }
139
140  void TestInsertDtmf(uint32_t ssrc, bool caller) {
141    EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
142    channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
143    EXPECT_TRUE(channel_ != nullptr);
144    if (caller) {
145      // If this is a caller, local description will be applied and add the
146      // send stream.
147      EXPECT_TRUE(channel_->AddSendStream(
148          cricket::StreamParams::CreateLegacy(kSsrc1)));
149    }
150
151    // Test we can only InsertDtmf when the other side supports telephone-event.
152    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
153    EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
154    EXPECT_FALSE(channel_->CanInsertDtmf());
155    EXPECT_FALSE(channel_->InsertDtmf(ssrc, 1, 111));
156    send_parameters_.codecs.push_back(kTelephoneEventCodec);
157    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
158    EXPECT_TRUE(channel_->CanInsertDtmf());
159
160    if (!caller) {
161      // If this is callee, there's no active send channel yet.
162      EXPECT_FALSE(channel_->InsertDtmf(ssrc, 2, 123));
163      EXPECT_TRUE(channel_->AddSendStream(
164          cricket::StreamParams::CreateLegacy(kSsrc1)));
165    }
166
167    // Check we fail if the ssrc is invalid.
168    EXPECT_FALSE(channel_->InsertDtmf(-1, 1, 111));
169
170    // Test send.
171    cricket::FakeAudioSendStream::TelephoneEvent telephone_event =
172        GetSendStream(kSsrc1).GetLatestTelephoneEvent();
173    EXPECT_EQ(-1, telephone_event.payload_type);
174    EXPECT_TRUE(channel_->InsertDtmf(ssrc, 2, 123));
175    telephone_event = GetSendStream(kSsrc1).GetLatestTelephoneEvent();
176    EXPECT_EQ(kTelephoneEventCodec.id, telephone_event.payload_type);
177    EXPECT_EQ(2, telephone_event.event_code);
178    EXPECT_EQ(123, telephone_event.duration_ms);
179  }
180
181  // Test that send bandwidth is set correctly.
182  // |codec| is the codec under test.
183  // |max_bitrate| is a parameter to set to SetMaxSendBandwidth().
184  // |expected_result| is the expected result from SetMaxSendBandwidth().
185  // |expected_bitrate| is the expected audio bitrate afterward.
186  void TestSendBandwidth(const cricket::AudioCodec& codec,
187                         int max_bitrate,
188                         bool expected_result,
189                         int expected_bitrate) {
190    cricket::AudioSendParameters parameters;
191    parameters.codecs.push_back(codec);
192    parameters.max_bandwidth_bps = max_bitrate;
193    EXPECT_EQ(expected_result, channel_->SetSendParameters(parameters));
194
195    int channel_num = voe_.GetLastChannel();
196    webrtc::CodecInst temp_codec;
197    EXPECT_FALSE(voe_.GetSendCodec(channel_num, temp_codec));
198    EXPECT_EQ(expected_bitrate, temp_codec.rate);
199  }
200
201  void TestSetSendRtpHeaderExtensions(const std::string& ext) {
202    EXPECT_TRUE(SetupEngineWithSendStream());
203
204    // Ensure extensions are off by default.
205    EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
206
207    // Ensure unknown extensions won't cause an error.
208    send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
209        "urn:ietf:params:unknownextention", 1));
210    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
211    EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
212
213    // Ensure extensions stay off with an empty list of headers.
214    send_parameters_.extensions.clear();
215    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
216    EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
217
218    // Ensure extension is set properly.
219    const int id = 1;
220    send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
221    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
222    EXPECT_EQ(1u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
223    EXPECT_EQ(ext, GetSendStreamConfig(kSsrc1).rtp.extensions[0].name);
224    EXPECT_EQ(id, GetSendStreamConfig(kSsrc1).rtp.extensions[0].id);
225
226    // Ensure extension is set properly on new stream.
227    EXPECT_TRUE(channel_->AddSendStream(
228        cricket::StreamParams::CreateLegacy(kSsrc2)));
229    EXPECT_NE(call_.GetAudioSendStream(kSsrc1),
230              call_.GetAudioSendStream(kSsrc2));
231    EXPECT_EQ(1u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
232    EXPECT_EQ(ext, GetSendStreamConfig(kSsrc2).rtp.extensions[0].name);
233    EXPECT_EQ(id, GetSendStreamConfig(kSsrc2).rtp.extensions[0].id);
234
235    // Ensure all extensions go back off with an empty list.
236    send_parameters_.codecs.push_back(kPcmuCodec);
237    send_parameters_.extensions.clear();
238    EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
239    EXPECT_EQ(0u, GetSendStreamConfig(kSsrc1).rtp.extensions.size());
240    EXPECT_EQ(0u, GetSendStreamConfig(kSsrc2).rtp.extensions.size());
241  }
242
243  void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
244    EXPECT_TRUE(SetupEngineWithRecvStream());
245
246    // Ensure extensions are off by default.
247    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
248
249    // Ensure unknown extensions won't cause an error.
250    recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
251        "urn:ietf:params:unknownextention", 1));
252    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
253    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
254
255    // Ensure extensions stay off with an empty list of headers.
256    recv_parameters_.extensions.clear();
257    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
258    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
259
260    // Ensure extension is set properly.
261    const int id = 2;
262    recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(ext, id));
263    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
264    EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
265    EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].name);
266    EXPECT_EQ(id, GetRecvStreamConfig(kSsrc1).rtp.extensions[0].id);
267
268    // Ensure extension is set properly on new stream.
269    EXPECT_TRUE(channel_->AddRecvStream(
270        cricket::StreamParams::CreateLegacy(kSsrc2)));
271    EXPECT_NE(call_.GetAudioReceiveStream(kSsrc1),
272              call_.GetAudioReceiveStream(kSsrc2));
273    EXPECT_EQ(1u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
274    EXPECT_EQ(ext, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].name);
275    EXPECT_EQ(id, GetRecvStreamConfig(kSsrc2).rtp.extensions[0].id);
276
277    // Ensure all extensions go back off with an empty list.
278    recv_parameters_.extensions.clear();
279    EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
280    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc1).rtp.extensions.size());
281    EXPECT_EQ(0u, GetRecvStreamConfig(kSsrc2).rtp.extensions.size());
282  }
283
284  webrtc::AudioSendStream::Stats GetAudioSendStreamStats() const {
285    webrtc::AudioSendStream::Stats stats;
286    stats.local_ssrc = 12;
287    stats.bytes_sent = 345;
288    stats.packets_sent = 678;
289    stats.packets_lost = 9012;
290    stats.fraction_lost = 34.56f;
291    stats.codec_name = "codec_name_send";
292    stats.ext_seqnum = 789;
293    stats.jitter_ms = 12;
294    stats.rtt_ms = 345;
295    stats.audio_level = 678;
296    stats.aec_quality_min = 9.01f;
297    stats.echo_delay_median_ms = 234;
298    stats.echo_delay_std_ms = 567;
299    stats.echo_return_loss = 890;
300    stats.echo_return_loss_enhancement = 1234;
301    stats.typing_noise_detected = true;
302    return stats;
303  }
304  void SetAudioSendStreamStats() {
305    for (auto* s : call_.GetAudioSendStreams()) {
306      s->SetStats(GetAudioSendStreamStats());
307    }
308  }
309  void VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo& info,
310                             bool is_sending) {
311    const auto stats = GetAudioSendStreamStats();
312    EXPECT_EQ(info.ssrc(), stats.local_ssrc);
313    EXPECT_EQ(info.bytes_sent, stats.bytes_sent);
314    EXPECT_EQ(info.packets_sent, stats.packets_sent);
315    EXPECT_EQ(info.packets_lost, stats.packets_lost);
316    EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
317    EXPECT_EQ(info.codec_name, stats.codec_name);
318    EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
319    EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
320    EXPECT_EQ(info.rtt_ms, stats.rtt_ms);
321    EXPECT_EQ(info.audio_level, stats.audio_level);
322    EXPECT_EQ(info.aec_quality_min, stats.aec_quality_min);
323    EXPECT_EQ(info.echo_delay_median_ms, stats.echo_delay_median_ms);
324    EXPECT_EQ(info.echo_delay_std_ms, stats.echo_delay_std_ms);
325    EXPECT_EQ(info.echo_return_loss, stats.echo_return_loss);
326    EXPECT_EQ(info.echo_return_loss_enhancement,
327              stats.echo_return_loss_enhancement);
328    EXPECT_EQ(info.typing_noise_detected,
329              stats.typing_noise_detected && is_sending);
330  }
331
332  webrtc::AudioReceiveStream::Stats GetAudioReceiveStreamStats() const {
333    webrtc::AudioReceiveStream::Stats stats;
334    stats.remote_ssrc = 123;
335    stats.bytes_rcvd = 456;
336    stats.packets_rcvd = 768;
337    stats.packets_lost = 101;
338    stats.fraction_lost = 23.45f;
339    stats.codec_name = "codec_name_recv";
340    stats.ext_seqnum = 678;
341    stats.jitter_ms = 901;
342    stats.jitter_buffer_ms = 234;
343    stats.jitter_buffer_preferred_ms = 567;
344    stats.delay_estimate_ms = 890;
345    stats.audio_level = 1234;
346    stats.expand_rate = 5.67f;
347    stats.speech_expand_rate = 8.90f;
348    stats.secondary_decoded_rate = 1.23f;
349    stats.accelerate_rate = 4.56f;
350    stats.preemptive_expand_rate = 7.89f;
351    stats.decoding_calls_to_silence_generator = 12;
352    stats.decoding_calls_to_neteq = 345;
353    stats.decoding_normal = 67890;
354    stats.decoding_plc = 1234;
355    stats.decoding_cng = 5678;
356    stats.decoding_plc_cng = 9012;
357    stats.capture_start_ntp_time_ms = 3456;
358    return stats;
359  }
360  void SetAudioReceiveStreamStats() {
361    for (auto* s : call_.GetAudioReceiveStreams()) {
362      s->SetStats(GetAudioReceiveStreamStats());
363    }
364  }
365  void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) {
366    const auto stats = GetAudioReceiveStreamStats();
367    EXPECT_EQ(info.ssrc(), stats.remote_ssrc);
368    EXPECT_EQ(info.bytes_rcvd, stats.bytes_rcvd);
369    EXPECT_EQ(info.packets_rcvd, stats.packets_rcvd);
370    EXPECT_EQ(info.packets_lost, stats.packets_lost);
371    EXPECT_EQ(info.fraction_lost, stats.fraction_lost);
372    EXPECT_EQ(info.codec_name, stats.codec_name);
373    EXPECT_EQ(info.ext_seqnum, stats.ext_seqnum);
374    EXPECT_EQ(info.jitter_ms, stats.jitter_ms);
375    EXPECT_EQ(info.jitter_buffer_ms, stats.jitter_buffer_ms);
376    EXPECT_EQ(info.jitter_buffer_preferred_ms,
377              stats.jitter_buffer_preferred_ms);
378    EXPECT_EQ(info.delay_estimate_ms, stats.delay_estimate_ms);
379    EXPECT_EQ(info.audio_level, stats.audio_level);
380    EXPECT_EQ(info.expand_rate, stats.expand_rate);
381    EXPECT_EQ(info.speech_expand_rate, stats.speech_expand_rate);
382    EXPECT_EQ(info.secondary_decoded_rate, stats.secondary_decoded_rate);
383    EXPECT_EQ(info.accelerate_rate, stats.accelerate_rate);
384    EXPECT_EQ(info.preemptive_expand_rate, stats.preemptive_expand_rate);
385    EXPECT_EQ(info.decoding_calls_to_silence_generator,
386              stats.decoding_calls_to_silence_generator);
387    EXPECT_EQ(info.decoding_calls_to_neteq, stats.decoding_calls_to_neteq);
388    EXPECT_EQ(info.decoding_normal, stats.decoding_normal);
389    EXPECT_EQ(info.decoding_plc, stats.decoding_plc);
390    EXPECT_EQ(info.decoding_cng, stats.decoding_cng);
391    EXPECT_EQ(info.decoding_plc_cng, stats.decoding_plc_cng);
392    EXPECT_EQ(info.capture_start_ntp_time_ms, stats.capture_start_ntp_time_ms);
393  }
394
395 protected:
396  cricket::FakeCall call_;
397  cricket::FakeWebRtcVoiceEngine voe_;
398  cricket::WebRtcVoiceEngine engine_;
399  cricket::VoiceMediaChannel* channel_;
400  cricket::AudioSendParameters send_parameters_;
401  cricket::AudioRecvParameters recv_parameters_;
402};
403
404// Tests that our stub library "works".
405TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
406  EXPECT_FALSE(voe_.IsInited());
407  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
408  EXPECT_TRUE(voe_.IsInited());
409  engine_.Terminate();
410  EXPECT_FALSE(voe_.IsInited());
411}
412
413// Tests that we can create and destroy a channel.
414TEST_F(WebRtcVoiceEngineTestFake, CreateChannel) {
415  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
416  channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
417  EXPECT_TRUE(channel_ != nullptr);
418}
419
420// Tests that the list of supported codecs is created properly and ordered
421// correctly
422TEST_F(WebRtcVoiceEngineTestFake, CodecPreference) {
423  const std::vector<cricket::AudioCodec>& codecs = engine_.codecs();
424  ASSERT_FALSE(codecs.empty());
425  EXPECT_STRCASEEQ("opus", codecs[0].name.c_str());
426  EXPECT_EQ(48000, codecs[0].clockrate);
427  EXPECT_EQ(2, codecs[0].channels);
428  EXPECT_EQ(64000, codecs[0].bitrate);
429  int pref = codecs[0].preference;
430  for (size_t i = 1; i < codecs.size(); ++i) {
431    EXPECT_GT(pref, codecs[i].preference);
432    pref = codecs[i].preference;
433  }
434}
435
436// Tests that we can find codecs by name or id, and that we interpret the
437// clockrate and bitrate fields properly.
438TEST_F(WebRtcVoiceEngineTestFake, FindCodec) {
439  cricket::AudioCodec codec;
440  webrtc::CodecInst codec_inst;
441  // Find PCMU with explicit clockrate and bitrate.
442  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kPcmuCodec, &codec_inst));
443  // Find ISAC with explicit clockrate and 0 bitrate.
444  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kIsacCodec, &codec_inst));
445  // Find telephone-event with explicit clockrate and 0 bitrate.
446  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kTelephoneEventCodec,
447                                                      &codec_inst));
448  // Find ISAC with a different payload id.
449  codec = kIsacCodec;
450  codec.id = 127;
451  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
452  EXPECT_EQ(codec.id, codec_inst.pltype);
453  // Find PCMU with a 0 clockrate.
454  codec = kPcmuCodec;
455  codec.clockrate = 0;
456  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
457  EXPECT_EQ(codec.id, codec_inst.pltype);
458  EXPECT_EQ(8000, codec_inst.plfreq);
459  // Find PCMU with a 0 bitrate.
460  codec = kPcmuCodec;
461  codec.bitrate = 0;
462  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
463  EXPECT_EQ(codec.id, codec_inst.pltype);
464  EXPECT_EQ(64000, codec_inst.rate);
465  // Find ISAC with an explicit bitrate.
466  codec = kIsacCodec;
467  codec.bitrate = 32000;
468  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(codec, &codec_inst));
469  EXPECT_EQ(codec.id, codec_inst.pltype);
470  EXPECT_EQ(32000, codec_inst.rate);
471}
472
473// Test that we set our inbound codecs properly, including changing PT.
474TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecs) {
475  EXPECT_TRUE(SetupEngine());
476  cricket::AudioRecvParameters parameters;
477  parameters.codecs.push_back(kIsacCodec);
478  parameters.codecs.push_back(kPcmuCodec);
479  parameters.codecs.push_back(kTelephoneEventCodec);
480  parameters.codecs[0].id = 106;  // collide with existing telephone-event
481  parameters.codecs[2].id = 126;
482  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
483  EXPECT_TRUE(channel_->AddRecvStream(
484      cricket::StreamParams::CreateLegacy(kSsrc1)));
485  int channel_num = voe_.GetLastChannel();
486  webrtc::CodecInst gcodec;
487  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
488  gcodec.plfreq = 16000;
489  gcodec.channels = 1;
490  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
491  EXPECT_EQ(106, gcodec.pltype);
492  EXPECT_STREQ("ISAC", gcodec.plname);
493  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
494  gcodec.plfreq = 8000;
495  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, gcodec));
496  EXPECT_EQ(126, gcodec.pltype);
497  EXPECT_STREQ("telephone-event", gcodec.plname);
498}
499
500// Test that we fail to set an unknown inbound codec.
501TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsUnsupportedCodec) {
502  EXPECT_TRUE(SetupEngine());
503  cricket::AudioRecvParameters parameters;
504  parameters.codecs.push_back(kIsacCodec);
505  parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1, 0));
506  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
507}
508
509// Test that we fail if we have duplicate types in the inbound list.
510TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsDuplicatePayloadType) {
511  EXPECT_TRUE(SetupEngine());
512  cricket::AudioRecvParameters parameters;
513  parameters.codecs.push_back(kIsacCodec);
514  parameters.codecs.push_back(kCn16000Codec);
515  parameters.codecs[1].id = kIsacCodec.id;
516  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
517}
518
519// Test that we can decode OPUS without stereo parameters.
520TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpusNoStereo) {
521  EXPECT_TRUE(SetupEngine());
522  cricket::AudioRecvParameters parameters;
523  parameters.codecs.push_back(kIsacCodec);
524  parameters.codecs.push_back(kPcmuCodec);
525  parameters.codecs.push_back(kOpusCodec);
526  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
527  EXPECT_TRUE(channel_->AddRecvStream(
528      cricket::StreamParams::CreateLegacy(kSsrc1)));
529  int channel_num = voe_.GetLastChannel();
530  webrtc::CodecInst opus;
531  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
532  // Even without stereo parameters, recv codecs still specify channels = 2.
533  EXPECT_EQ(2, opus.channels);
534  EXPECT_EQ(111, opus.pltype);
535  EXPECT_STREQ("opus", opus.plname);
536  opus.pltype = 0;
537  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num, opus));
538  EXPECT_EQ(111, opus.pltype);
539}
540
541// Test that we can decode OPUS with stereo = 0.
542TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus0Stereo) {
543  EXPECT_TRUE(SetupEngine());
544  cricket::AudioRecvParameters parameters;
545  parameters.codecs.push_back(kIsacCodec);
546  parameters.codecs.push_back(kPcmuCodec);
547  parameters.codecs.push_back(kOpusCodec);
548  parameters.codecs[2].params["stereo"] = "0";
549  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
550  EXPECT_TRUE(channel_->AddRecvStream(
551      cricket::StreamParams::CreateLegacy(kSsrc1)));
552  int channel_num2 = voe_.GetLastChannel();
553  webrtc::CodecInst opus;
554  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
555  // Even when stereo is off, recv codecs still specify channels = 2.
556  EXPECT_EQ(2, opus.channels);
557  EXPECT_EQ(111, opus.pltype);
558  EXPECT_STREQ("opus", opus.plname);
559  opus.pltype = 0;
560  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
561  EXPECT_EQ(111, opus.pltype);
562}
563
564// Test that we can decode OPUS with stereo = 1.
565TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithOpus1Stereo) {
566  EXPECT_TRUE(SetupEngine());
567  cricket::AudioRecvParameters parameters;
568  parameters.codecs.push_back(kIsacCodec);
569  parameters.codecs.push_back(kPcmuCodec);
570  parameters.codecs.push_back(kOpusCodec);
571  parameters.codecs[2].params["stereo"] = "1";
572  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
573  EXPECT_TRUE(channel_->AddRecvStream(
574      cricket::StreamParams::CreateLegacy(kSsrc1)));
575  int channel_num2 = voe_.GetLastChannel();
576  webrtc::CodecInst opus;
577  cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &opus);
578  EXPECT_EQ(2, opus.channels);
579  EXPECT_EQ(111, opus.pltype);
580  EXPECT_STREQ("opus", opus.plname);
581  opus.pltype = 0;
582  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, opus));
583  EXPECT_EQ(111, opus.pltype);
584}
585
586// Test that changes to recv codecs are applied to all streams.
587TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWithMultipleStreams) {
588  EXPECT_TRUE(SetupEngine());
589  cricket::AudioRecvParameters parameters;
590  parameters.codecs.push_back(kIsacCodec);
591  parameters.codecs.push_back(kPcmuCodec);
592  parameters.codecs.push_back(kTelephoneEventCodec);
593  parameters.codecs[0].id = 106;  // collide with existing telephone-event
594  parameters.codecs[2].id = 126;
595  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
596  EXPECT_TRUE(channel_->AddRecvStream(
597      cricket::StreamParams::CreateLegacy(kSsrc1)));
598  int channel_num2 = voe_.GetLastChannel();
599  webrtc::CodecInst gcodec;
600  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
601  gcodec.plfreq = 16000;
602  gcodec.channels = 1;
603  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
604  EXPECT_EQ(106, gcodec.pltype);
605  EXPECT_STREQ("ISAC", gcodec.plname);
606  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "telephone-event");
607  gcodec.plfreq = 8000;
608  gcodec.channels = 1;
609  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
610  EXPECT_EQ(126, gcodec.pltype);
611  EXPECT_STREQ("telephone-event", gcodec.plname);
612}
613
614TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsAfterAddingStreams) {
615  EXPECT_TRUE(SetupEngineWithRecvStream());
616  cricket::AudioRecvParameters parameters;
617  parameters.codecs.push_back(kIsacCodec);
618  parameters.codecs[0].id = 106;  // collide with existing telephone-event
619  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
620
621  int channel_num2 = voe_.GetLastChannel();
622  webrtc::CodecInst gcodec;
623  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "ISAC");
624  gcodec.plfreq = 16000;
625  gcodec.channels = 1;
626  EXPECT_EQ(0, voe_.GetRecPayloadType(channel_num2, gcodec));
627  EXPECT_EQ(106, gcodec.pltype);
628  EXPECT_STREQ("ISAC", gcodec.plname);
629}
630
631// Test that we can apply the same set of codecs again while playing.
632TEST_F(WebRtcVoiceEngineTestFake, SetRecvCodecsWhilePlaying) {
633  EXPECT_TRUE(SetupEngineWithRecvStream());
634  cricket::AudioRecvParameters parameters;
635  parameters.codecs.push_back(kIsacCodec);
636  parameters.codecs.push_back(kCn16000Codec);
637  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
638  EXPECT_TRUE(channel_->SetPlayout(true));
639  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
640
641  // Changing the payload type of a codec should fail.
642  parameters.codecs[0].id = 127;
643  EXPECT_FALSE(channel_->SetRecvParameters(parameters));
644  int channel_num = voe_.GetLastChannel();
645  EXPECT_TRUE(voe_.GetPlayout(channel_num));
646}
647
648// Test that we can add a codec while playing.
649TEST_F(WebRtcVoiceEngineTestFake, AddRecvCodecsWhilePlaying) {
650  EXPECT_TRUE(SetupEngineWithRecvStream());
651  cricket::AudioRecvParameters parameters;
652  parameters.codecs.push_back(kIsacCodec);
653  parameters.codecs.push_back(kCn16000Codec);
654  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
655  EXPECT_TRUE(channel_->SetPlayout(true));
656
657  parameters.codecs.push_back(kOpusCodec);
658  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
659  int channel_num = voe_.GetLastChannel();
660  EXPECT_TRUE(voe_.GetPlayout(channel_num));
661  webrtc::CodecInst gcodec;
662  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(kOpusCodec, &gcodec));
663  EXPECT_EQ(kOpusCodec.id, gcodec.pltype);
664}
665
666TEST_F(WebRtcVoiceEngineTestFake, SetSendBandwidthAuto) {
667  EXPECT_TRUE(SetupEngineWithSendStream());
668
669  // Test that when autobw is enabled, bitrate is kept as the default
670  // value. autobw is enabled for the following tests because the target
671  // bitrate is <= 0.
672
673  // ISAC, default bitrate == 32000.
674  TestSendBandwidth(kIsacCodec, 0, true, 32000);
675
676  // PCMU, default bitrate == 64000.
677  TestSendBandwidth(kPcmuCodec, -1, true, 64000);
678
679  // opus, default bitrate == 64000.
680  TestSendBandwidth(kOpusCodec, -1, true, 64000);
681}
682
683TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCaller) {
684  EXPECT_TRUE(SetupEngineWithSendStream());
685
686  // Test that the bitrate of a multi-rate codec is always the maximum.
687
688  // ISAC, default bitrate == 32000.
689  TestSendBandwidth(kIsacCodec, 128000, true, 128000);
690  TestSendBandwidth(kIsacCodec, 16000, true, 16000);
691
692  // opus, default bitrate == 64000.
693  TestSendBandwidth(kOpusCodec, 96000, true, 96000);
694  TestSendBandwidth(kOpusCodec, 48000, true, 48000);
695}
696
697TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthFixedRateAsCaller) {
698  EXPECT_TRUE(SetupEngineWithSendStream());
699
700  // Test that we can only set a maximum bitrate for a fixed-rate codec
701  // if it's bigger than the fixed rate.
702
703  // PCMU, fixed bitrate == 64000.
704  TestSendBandwidth(kPcmuCodec, 0, true, 64000);
705  TestSendBandwidth(kPcmuCodec, 1, false, 64000);
706  TestSendBandwidth(kPcmuCodec, 128000, true, 64000);
707  TestSendBandwidth(kPcmuCodec, 32000, false, 64000);
708  TestSendBandwidth(kPcmuCodec, 64000, true, 64000);
709  TestSendBandwidth(kPcmuCodec, 63999, false, 64000);
710  TestSendBandwidth(kPcmuCodec, 64001, true, 64000);
711}
712
713TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthMultiRateAsCallee) {
714  EXPECT_TRUE(SetupEngine());
715  const int kDesiredBitrate = 128000;
716  cricket::AudioSendParameters parameters;
717  parameters.codecs = engine_.codecs();
718  parameters.max_bandwidth_bps = kDesiredBitrate;
719  EXPECT_TRUE(channel_->SetSendParameters(parameters));
720
721  EXPECT_TRUE(channel_->AddSendStream(
722      cricket::StreamParams::CreateLegacy(kSsrc1)));
723
724  int channel_num = voe_.GetLastChannel();
725  webrtc::CodecInst codec;
726  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
727  EXPECT_EQ(kDesiredBitrate, codec.rate);
728}
729
730// Test that bitrate cannot be set for CBR codecs.
731// Bitrate is ignored if it is higher than the fixed bitrate.
732// Bitrate less then the fixed bitrate is an error.
733TEST_F(WebRtcVoiceEngineTestFake, SetMaxSendBandwidthCbr) {
734  EXPECT_TRUE(SetupEngineWithSendStream());
735
736  // PCMU, default bitrate == 64000.
737  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
738  int channel_num = voe_.GetLastChannel();
739  webrtc::CodecInst codec;
740  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
741  EXPECT_EQ(64000, codec.rate);
742
743  send_parameters_.max_bandwidth_bps = 128000;
744  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
745  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
746  EXPECT_EQ(64000, codec.rate);
747
748  send_parameters_.max_bandwidth_bps = 128;
749  EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
750  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, codec));
751  EXPECT_EQ(64000, codec.rate);
752}
753
754// Test that we apply codecs properly.
755TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecs) {
756  EXPECT_TRUE(SetupEngineWithSendStream());
757  cricket::AudioSendParameters parameters;
758  parameters.codecs.push_back(kIsacCodec);
759  parameters.codecs.push_back(kPcmuCodec);
760  parameters.codecs.push_back(kRedCodec);
761  parameters.codecs[0].id = 96;
762  parameters.codecs[0].bitrate = 48000;
763  EXPECT_TRUE(channel_->SetSendParameters(parameters));
764  EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
765  int channel_num = voe_.GetLastChannel();
766  webrtc::CodecInst gcodec;
767  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
768  EXPECT_EQ(96, gcodec.pltype);
769  EXPECT_EQ(48000, gcodec.rate);
770  EXPECT_STREQ("ISAC", gcodec.plname);
771  EXPECT_FALSE(voe_.GetVAD(channel_num));
772  EXPECT_FALSE(voe_.GetRED(channel_num));
773  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
774  EXPECT_EQ(105, voe_.GetSendCNPayloadType(channel_num, true));
775  EXPECT_FALSE(channel_->CanInsertDtmf());
776}
777
778// Test that VoE Channel doesn't call SetSendCodec again if same codec is tried
779// to apply.
780TEST_F(WebRtcVoiceEngineTestFake, DontResetSetSendCodec) {
781  EXPECT_TRUE(SetupEngineWithSendStream());
782  cricket::AudioSendParameters parameters;
783  parameters.codecs.push_back(kIsacCodec);
784  parameters.codecs.push_back(kPcmuCodec);
785  parameters.codecs.push_back(kRedCodec);
786  parameters.codecs[0].id = 96;
787  parameters.codecs[0].bitrate = 48000;
788  EXPECT_TRUE(channel_->SetSendParameters(parameters));
789  EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
790  // Calling SetSendCodec again with same codec which is already set.
791  // In this case media channel shouldn't send codec to VoE.
792  EXPECT_TRUE(channel_->SetSendParameters(parameters));
793  EXPECT_EQ(1, voe_.GetNumSetSendCodecs());
794}
795
796// Verify that G722 is set with 16000 samples per second to WebRTC.
797TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecG722) {
798  EXPECT_TRUE(SetupEngineWithSendStream());
799  int channel_num = voe_.GetLastChannel();
800  cricket::AudioSendParameters parameters;
801  parameters.codecs.push_back(kG722CodecSdp);
802  EXPECT_TRUE(channel_->SetSendParameters(parameters));
803  webrtc::CodecInst gcodec;
804  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
805  EXPECT_STREQ("G722", gcodec.plname);
806  EXPECT_EQ(1, gcodec.channels);
807  EXPECT_EQ(16000, gcodec.plfreq);
808}
809
810// Test that if clockrate is not 48000 for opus, we fail.
811TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBadClockrate) {
812  EXPECT_TRUE(SetupEngineWithSendStream());
813  cricket::AudioSendParameters parameters;
814  parameters.codecs.push_back(kOpusCodec);
815  parameters.codecs[0].bitrate = 0;
816  parameters.codecs[0].clockrate = 50000;
817  EXPECT_FALSE(channel_->SetSendParameters(parameters));
818}
819
820// Test that if channels=0 for opus, we fail.
821TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0ChannelsNoStereo) {
822  EXPECT_TRUE(SetupEngineWithSendStream());
823  cricket::AudioSendParameters parameters;
824  parameters.codecs.push_back(kOpusCodec);
825  parameters.codecs[0].bitrate = 0;
826  parameters.codecs[0].channels = 0;
827  EXPECT_FALSE(channel_->SetSendParameters(parameters));
828}
829
830// Test that if channels=0 for opus, we fail.
831TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad0Channels1Stereo) {
832  EXPECT_TRUE(SetupEngineWithSendStream());
833  cricket::AudioSendParameters parameters;
834  parameters.codecs.push_back(kOpusCodec);
835  parameters.codecs[0].bitrate = 0;
836  parameters.codecs[0].channels = 0;
837  parameters.codecs[0].params["stereo"] = "1";
838  EXPECT_FALSE(channel_->SetSendParameters(parameters));
839}
840
841// Test that if channel is 1 for opus and there's no stereo, we fail.
842TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpus1ChannelNoStereo) {
843  EXPECT_TRUE(SetupEngineWithSendStream());
844  cricket::AudioSendParameters parameters;
845  parameters.codecs.push_back(kOpusCodec);
846  parameters.codecs[0].bitrate = 0;
847  parameters.codecs[0].channels = 1;
848  EXPECT_FALSE(channel_->SetSendParameters(parameters));
849}
850
851// Test that if channel is 1 for opus and stereo=0, we fail.
852TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel0Stereo) {
853  EXPECT_TRUE(SetupEngineWithSendStream());
854  cricket::AudioSendParameters parameters;
855  parameters.codecs.push_back(kOpusCodec);
856  parameters.codecs[0].bitrate = 0;
857  parameters.codecs[0].channels = 1;
858  parameters.codecs[0].params["stereo"] = "0";
859  EXPECT_FALSE(channel_->SetSendParameters(parameters));
860}
861
862// Test that if channel is 1 for opus and stereo=1, we fail.
863TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusBad1Channel1Stereo) {
864  EXPECT_TRUE(SetupEngineWithSendStream());
865  cricket::AudioSendParameters parameters;
866  parameters.codecs.push_back(kOpusCodec);
867  parameters.codecs[0].bitrate = 0;
868  parameters.codecs[0].channels = 1;
869  parameters.codecs[0].params["stereo"] = "1";
870  EXPECT_FALSE(channel_->SetSendParameters(parameters));
871}
872
873// Test that with bitrate=0 and no stereo,
874// channels and bitrate are 1 and 32000.
875TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0BitrateNoStereo) {
876  EXPECT_TRUE(SetupEngineWithSendStream());
877  int channel_num = voe_.GetLastChannel();
878  cricket::AudioSendParameters parameters;
879  parameters.codecs.push_back(kOpusCodec);
880  parameters.codecs[0].bitrate = 0;
881  EXPECT_TRUE(channel_->SetSendParameters(parameters));
882  webrtc::CodecInst gcodec;
883  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
884  EXPECT_STREQ("opus", gcodec.plname);
885  EXPECT_EQ(1, gcodec.channels);
886  EXPECT_EQ(32000, gcodec.rate);
887}
888
889// Test that with bitrate=0 and stereo=0,
890// channels and bitrate are 1 and 32000.
891TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate0Stereo) {
892  EXPECT_TRUE(SetupEngineWithSendStream());
893  int channel_num = voe_.GetLastChannel();
894  cricket::AudioSendParameters parameters;
895  parameters.codecs.push_back(kOpusCodec);
896  parameters.codecs[0].bitrate = 0;
897  parameters.codecs[0].params["stereo"] = "0";
898  EXPECT_TRUE(channel_->SetSendParameters(parameters));
899  webrtc::CodecInst gcodec;
900  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
901  EXPECT_STREQ("opus", gcodec.plname);
902  EXPECT_EQ(1, gcodec.channels);
903  EXPECT_EQ(32000, gcodec.rate);
904}
905
906// Test that with bitrate=invalid and stereo=0,
907// channels and bitrate are 1 and 32000.
908TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate0Stereo) {
909  EXPECT_TRUE(SetupEngineWithSendStream());
910  int channel_num = voe_.GetLastChannel();
911  cricket::AudioSendParameters parameters;
912  parameters.codecs.push_back(kOpusCodec);
913  parameters.codecs[0].params["stereo"] = "0";
914  webrtc::CodecInst gcodec;
915
916  // bitrate that's out of the range between 6000 and 510000 will be clamped.
917  parameters.codecs[0].bitrate = 5999;
918  EXPECT_TRUE(channel_->SetSendParameters(parameters));
919  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
920  EXPECT_STREQ("opus", gcodec.plname);
921  EXPECT_EQ(1, gcodec.channels);
922  EXPECT_EQ(6000, gcodec.rate);
923
924  parameters.codecs[0].bitrate = 510001;
925  EXPECT_TRUE(channel_->SetSendParameters(parameters));
926  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
927  EXPECT_STREQ("opus", gcodec.plname);
928  EXPECT_EQ(1, gcodec.channels);
929  EXPECT_EQ(510000, gcodec.rate);
930}
931
932// Test that with bitrate=0 and stereo=1,
933// channels and bitrate are 2 and 64000.
934TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGood0Bitrate1Stereo) {
935  EXPECT_TRUE(SetupEngineWithSendStream());
936  int channel_num = voe_.GetLastChannel();
937  cricket::AudioSendParameters parameters;
938  parameters.codecs.push_back(kOpusCodec);
939  parameters.codecs[0].bitrate = 0;
940  parameters.codecs[0].params["stereo"] = "1";
941  EXPECT_TRUE(channel_->SetSendParameters(parameters));
942  webrtc::CodecInst gcodec;
943  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
944  EXPECT_STREQ("opus", gcodec.plname);
945  EXPECT_EQ(2, gcodec.channels);
946  EXPECT_EQ(64000, gcodec.rate);
947}
948
949// Test that with bitrate=invalid and stereo=1,
950// channels and bitrate are 2 and 64000.
951TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodXBitrate1Stereo) {
952  EXPECT_TRUE(SetupEngineWithSendStream());
953  int channel_num = voe_.GetLastChannel();
954  cricket::AudioSendParameters parameters;
955  parameters.codecs.push_back(kOpusCodec);
956  parameters.codecs[0].params["stereo"] = "1";
957  webrtc::CodecInst gcodec;
958
959  // bitrate that's out of the range between 6000 and 510000 will be clamped.
960  parameters.codecs[0].bitrate = 5999;
961  EXPECT_TRUE(channel_->SetSendParameters(parameters));
962  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
963  EXPECT_STREQ("opus", gcodec.plname);
964  EXPECT_EQ(2, gcodec.channels);
965  EXPECT_EQ(6000, gcodec.rate);
966
967  parameters.codecs[0].bitrate = 510001;
968  EXPECT_TRUE(channel_->SetSendParameters(parameters));
969  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
970  EXPECT_STREQ("opus", gcodec.plname);
971  EXPECT_EQ(2, gcodec.channels);
972  EXPECT_EQ(510000, gcodec.rate);
973}
974
975// Test that with bitrate=N and stereo unset,
976// channels and bitrate are 1 and N.
977TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoStereo) {
978  EXPECT_TRUE(SetupEngineWithSendStream());
979  int channel_num = voe_.GetLastChannel();
980  cricket::AudioSendParameters parameters;
981  parameters.codecs.push_back(kOpusCodec);
982  parameters.codecs[0].bitrate = 96000;
983  EXPECT_TRUE(channel_->SetSendParameters(parameters));
984  webrtc::CodecInst gcodec;
985  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
986  EXPECT_EQ(111, gcodec.pltype);
987  EXPECT_EQ(96000, gcodec.rate);
988  EXPECT_STREQ("opus", gcodec.plname);
989  EXPECT_EQ(1, gcodec.channels);
990  EXPECT_EQ(48000, gcodec.plfreq);
991}
992
993// Test that with bitrate=N and stereo=0,
994// channels and bitrate are 1 and N.
995TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate0Stereo) {
996  EXPECT_TRUE(SetupEngineWithSendStream());
997  int channel_num = voe_.GetLastChannel();
998  cricket::AudioSendParameters parameters;
999  parameters.codecs.push_back(kOpusCodec);
1000  parameters.codecs[0].bitrate = 30000;
1001  parameters.codecs[0].params["stereo"] = "0";
1002  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1003  webrtc::CodecInst gcodec;
1004  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1005  EXPECT_EQ(1, gcodec.channels);
1006  EXPECT_EQ(30000, gcodec.rate);
1007  EXPECT_STREQ("opus", gcodec.plname);
1008}
1009
1010// Test that with bitrate=N and without any parameters,
1011// channels and bitrate are 1 and N.
1012TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrateNoParameters) {
1013  EXPECT_TRUE(SetupEngineWithSendStream());
1014  int channel_num = voe_.GetLastChannel();
1015  cricket::AudioSendParameters parameters;
1016  parameters.codecs.push_back(kOpusCodec);
1017  parameters.codecs[0].bitrate = 30000;
1018  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1019  webrtc::CodecInst gcodec;
1020  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1021  EXPECT_EQ(1, gcodec.channels);
1022  EXPECT_EQ(30000, gcodec.rate);
1023  EXPECT_STREQ("opus", gcodec.plname);
1024}
1025
1026// Test that with bitrate=N and stereo=1,
1027// channels and bitrate are 2 and N.
1028TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusGoodNBitrate1Stereo) {
1029  EXPECT_TRUE(SetupEngineWithSendStream());
1030  int channel_num = voe_.GetLastChannel();
1031  cricket::AudioSendParameters parameters;
1032  parameters.codecs.push_back(kOpusCodec);
1033  parameters.codecs[0].bitrate = 30000;
1034  parameters.codecs[0].params["stereo"] = "1";
1035  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1036  webrtc::CodecInst gcodec;
1037  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1038  EXPECT_EQ(2, gcodec.channels);
1039  EXPECT_EQ(30000, gcodec.rate);
1040  EXPECT_STREQ("opus", gcodec.plname);
1041}
1042
1043// Test that bitrate will be overridden by the "maxaveragebitrate" parameter.
1044// Also test that the "maxaveragebitrate" can't be set to values outside the
1045// range of 6000 and 510000
1046TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusMaxAverageBitrate) {
1047  EXPECT_TRUE(SetupEngineWithSendStream());
1048  int channel_num = voe_.GetLastChannel();
1049  cricket::AudioSendParameters parameters;
1050  parameters.codecs.push_back(kOpusCodec);
1051  parameters.codecs[0].bitrate = 30000;
1052  webrtc::CodecInst gcodec;
1053
1054  // Ignore if less than 6000.
1055  parameters.codecs[0].params["maxaveragebitrate"] = "5999";
1056  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1057  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1058  EXPECT_EQ(6000, gcodec.rate);
1059
1060  // Ignore if larger than 510000.
1061  parameters.codecs[0].params["maxaveragebitrate"] = "510001";
1062  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1063  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1064  EXPECT_EQ(510000, gcodec.rate);
1065
1066  parameters.codecs[0].params["maxaveragebitrate"] = "200000";
1067  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1068  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1069  EXPECT_EQ(200000, gcodec.rate);
1070}
1071
1072// Test that we can enable NACK with opus as caller.
1073TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCaller) {
1074  EXPECT_TRUE(SetupEngineWithSendStream());
1075  int channel_num = voe_.GetLastChannel();
1076  cricket::AudioSendParameters parameters;
1077  parameters.codecs.push_back(kOpusCodec);
1078  parameters.codecs[0].AddFeedbackParam(
1079      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1080                             cricket::kParamValueEmpty));
1081  EXPECT_FALSE(voe_.GetNACK(channel_num));
1082  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1083  EXPECT_TRUE(voe_.GetNACK(channel_num));
1084}
1085
1086// Test that we can enable NACK with opus as callee.
1087TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackAsCallee) {
1088  EXPECT_TRUE(SetupEngineWithRecvStream());
1089  int channel_num = voe_.GetLastChannel();
1090  cricket::AudioSendParameters parameters;
1091  parameters.codecs.push_back(kOpusCodec);
1092  parameters.codecs[0].AddFeedbackParam(
1093      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1094                             cricket::kParamValueEmpty));
1095  EXPECT_FALSE(voe_.GetNACK(channel_num));
1096  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1097  EXPECT_FALSE(voe_.GetNACK(channel_num));
1098
1099  EXPECT_TRUE(channel_->AddSendStream(
1100      cricket::StreamParams::CreateLegacy(kSsrc1)));
1101  EXPECT_TRUE(voe_.GetNACK(voe_.GetLastChannel()));
1102}
1103
1104// Test that we can enable NACK on receive streams.
1105TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecEnableNackRecvStreams) {
1106  EXPECT_TRUE(SetupEngineWithSendStream());
1107  int channel_num1 = voe_.GetLastChannel();
1108  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1109  int channel_num2 = voe_.GetLastChannel();
1110  cricket::AudioSendParameters parameters;
1111  parameters.codecs.push_back(kOpusCodec);
1112  parameters.codecs[0].AddFeedbackParam(
1113      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1114                             cricket::kParamValueEmpty));
1115  EXPECT_FALSE(voe_.GetNACK(channel_num1));
1116  EXPECT_FALSE(voe_.GetNACK(channel_num2));
1117  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1118  EXPECT_TRUE(voe_.GetNACK(channel_num1));
1119  EXPECT_TRUE(voe_.GetNACK(channel_num2));
1120}
1121
1122// Test that we can disable NACK.
1123TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNack) {
1124  EXPECT_TRUE(SetupEngineWithSendStream());
1125  int channel_num = voe_.GetLastChannel();
1126  cricket::AudioSendParameters parameters;
1127  parameters.codecs.push_back(kOpusCodec);
1128  parameters.codecs[0].AddFeedbackParam(
1129      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1130                             cricket::kParamValueEmpty));
1131  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1132  EXPECT_TRUE(voe_.GetNACK(channel_num));
1133
1134  parameters.codecs.clear();
1135  parameters.codecs.push_back(kOpusCodec);
1136  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1137  EXPECT_FALSE(voe_.GetNACK(channel_num));
1138}
1139
1140// Test that we can disable NACK on receive streams.
1141TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecDisableNackRecvStreams) {
1142  EXPECT_TRUE(SetupEngineWithSendStream());
1143  int channel_num1 = voe_.GetLastChannel();
1144  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1145  int channel_num2 = voe_.GetLastChannel();
1146  cricket::AudioSendParameters parameters;
1147  parameters.codecs.push_back(kOpusCodec);
1148  parameters.codecs[0].AddFeedbackParam(
1149      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1150                             cricket::kParamValueEmpty));
1151  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1152  EXPECT_TRUE(voe_.GetNACK(channel_num1));
1153  EXPECT_TRUE(voe_.GetNACK(channel_num2));
1154
1155  parameters.codecs.clear();
1156  parameters.codecs.push_back(kOpusCodec);
1157  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1158  EXPECT_FALSE(voe_.GetNACK(channel_num1));
1159  EXPECT_FALSE(voe_.GetNACK(channel_num2));
1160}
1161
1162// Test that NACK is enabled on a new receive stream.
1163TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamEnableNack) {
1164  EXPECT_TRUE(SetupEngineWithSendStream());
1165  int channel_num = voe_.GetLastChannel();
1166  cricket::AudioSendParameters parameters;
1167  parameters.codecs.push_back(kIsacCodec);
1168  parameters.codecs.push_back(kCn16000Codec);
1169  parameters.codecs[0].AddFeedbackParam(
1170      cricket::FeedbackParam(cricket::kRtcpFbParamNack,
1171                             cricket::kParamValueEmpty));
1172  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1173  EXPECT_TRUE(voe_.GetNACK(channel_num));
1174
1175  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1176  channel_num = voe_.GetLastChannel();
1177  EXPECT_TRUE(voe_.GetNACK(channel_num));
1178  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
1179  channel_num = voe_.GetLastChannel();
1180  EXPECT_TRUE(voe_.GetNACK(channel_num));
1181}
1182
1183// Test that without useinbandfec, Opus FEC is off.
1184TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecNoOpusFec) {
1185  EXPECT_TRUE(SetupEngineWithSendStream());
1186  int channel_num = voe_.GetLastChannel();
1187  cricket::AudioSendParameters parameters;
1188  parameters.codecs.push_back(kOpusCodec);
1189  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1190  EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1191}
1192
1193// Test that with useinbandfec=0, Opus FEC is off.
1194TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusDisableFec) {
1195  EXPECT_TRUE(SetupEngineWithSendStream());
1196  int channel_num = voe_.GetLastChannel();
1197  cricket::AudioSendParameters parameters;
1198  parameters.codecs.push_back(kOpusCodec);
1199  parameters.codecs[0].bitrate = 0;
1200  parameters.codecs[0].params["useinbandfec"] = "0";
1201  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1202  EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1203  webrtc::CodecInst gcodec;
1204  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1205  EXPECT_STREQ("opus", gcodec.plname);
1206  EXPECT_EQ(1, gcodec.channels);
1207  EXPECT_EQ(32000, gcodec.rate);
1208}
1209
1210// Test that with useinbandfec=1, Opus FEC is on.
1211TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFec) {
1212  EXPECT_TRUE(SetupEngineWithSendStream());
1213  int channel_num = voe_.GetLastChannel();
1214  cricket::AudioSendParameters parameters;
1215  parameters.codecs.push_back(kOpusCodec);
1216  parameters.codecs[0].bitrate = 0;
1217  parameters.codecs[0].params["useinbandfec"] = "1";
1218  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1219  EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1220  webrtc::CodecInst gcodec;
1221  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1222  EXPECT_STREQ("opus", gcodec.plname);
1223  EXPECT_EQ(1, gcodec.channels);
1224  EXPECT_EQ(32000, gcodec.rate);
1225}
1226
1227// Test that with useinbandfec=1, stereo=1, Opus FEC is on.
1228TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecOpusEnableFecStereo) {
1229  EXPECT_TRUE(SetupEngineWithSendStream());
1230  int channel_num = voe_.GetLastChannel();
1231  cricket::AudioSendParameters parameters;
1232  parameters.codecs.push_back(kOpusCodec);
1233  parameters.codecs[0].bitrate = 0;
1234  parameters.codecs[0].params["stereo"] = "1";
1235  parameters.codecs[0].params["useinbandfec"] = "1";
1236  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1237  EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1238  webrtc::CodecInst gcodec;
1239  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1240  EXPECT_STREQ("opus", gcodec.plname);
1241  EXPECT_EQ(2, gcodec.channels);
1242  EXPECT_EQ(64000, gcodec.rate);
1243}
1244
1245// Test that with non-Opus, codec FEC is off.
1246TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacNoFec) {
1247  EXPECT_TRUE(SetupEngineWithSendStream());
1248  int channel_num = voe_.GetLastChannel();
1249  cricket::AudioSendParameters parameters;
1250  parameters.codecs.push_back(kIsacCodec);
1251  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1252  EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1253}
1254
1255// Test the with non-Opus, even if useinbandfec=1, FEC is off.
1256TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecIsacWithParamNoFec) {
1257  EXPECT_TRUE(SetupEngineWithSendStream());
1258  int channel_num = voe_.GetLastChannel();
1259  cricket::AudioSendParameters parameters;
1260  parameters.codecs.push_back(kIsacCodec);
1261  parameters.codecs[0].params["useinbandfec"] = "1";
1262  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1263  EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1264}
1265
1266// Test that Opus FEC status can be changed.
1267TEST_F(WebRtcVoiceEngineTestFake, ChangeOpusFecStatus) {
1268  EXPECT_TRUE(SetupEngineWithSendStream());
1269  int channel_num = voe_.GetLastChannel();
1270  cricket::AudioSendParameters parameters;
1271  parameters.codecs.push_back(kOpusCodec);
1272  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1273  EXPECT_FALSE(voe_.GetCodecFEC(channel_num));
1274  parameters.codecs[0].params["useinbandfec"] = "1";
1275  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1276  EXPECT_TRUE(voe_.GetCodecFEC(channel_num));
1277}
1278
1279// Test maxplaybackrate <= 8000 triggers Opus narrow band mode.
1280TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateNb) {
1281  EXPECT_TRUE(SetupEngineWithSendStream());
1282  int channel_num = voe_.GetLastChannel();
1283  cricket::AudioSendParameters parameters;
1284  parameters.codecs.push_back(kOpusCodec);
1285  parameters.codecs[0].bitrate = 0;
1286  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1287  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1288  EXPECT_EQ(cricket::kOpusBandwidthNb,
1289            voe_.GetMaxEncodingBandwidth(channel_num));
1290  webrtc::CodecInst gcodec;
1291  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1292  EXPECT_STREQ("opus", gcodec.plname);
1293
1294  EXPECT_EQ(12000, gcodec.rate);
1295  parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1296  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1297  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1298  EXPECT_EQ(24000, gcodec.rate);
1299}
1300
1301// Test 8000 < maxplaybackrate <= 12000 triggers Opus medium band mode.
1302TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateMb) {
1303  EXPECT_TRUE(SetupEngineWithSendStream());
1304  int channel_num = voe_.GetLastChannel();
1305  cricket::AudioSendParameters parameters;
1306  parameters.codecs.push_back(kOpusCodec);
1307  parameters.codecs[0].bitrate = 0;
1308  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8001);
1309  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1310  EXPECT_EQ(cricket::kOpusBandwidthMb,
1311            voe_.GetMaxEncodingBandwidth(channel_num));
1312  webrtc::CodecInst gcodec;
1313  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1314  EXPECT_STREQ("opus", gcodec.plname);
1315
1316  EXPECT_EQ(20000, gcodec.rate);
1317  parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1318  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1319  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1320  EXPECT_EQ(40000, gcodec.rate);
1321}
1322
1323// Test 12000 < maxplaybackrate <= 16000 triggers Opus wide band mode.
1324TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateWb) {
1325  EXPECT_TRUE(SetupEngineWithSendStream());
1326  int channel_num = voe_.GetLastChannel();
1327  cricket::AudioSendParameters parameters;
1328  parameters.codecs.push_back(kOpusCodec);
1329  parameters.codecs[0].bitrate = 0;
1330  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 12001);
1331  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1332  EXPECT_EQ(cricket::kOpusBandwidthWb,
1333            voe_.GetMaxEncodingBandwidth(channel_num));
1334  webrtc::CodecInst gcodec;
1335  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1336  EXPECT_STREQ("opus", gcodec.plname);
1337
1338  EXPECT_EQ(20000, gcodec.rate);
1339  parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1340  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1341  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1342  EXPECT_EQ(40000, gcodec.rate);
1343}
1344
1345// Test 16000 < maxplaybackrate <= 24000 triggers Opus super wide band mode.
1346TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateSwb) {
1347  EXPECT_TRUE(SetupEngineWithSendStream());
1348  int channel_num = voe_.GetLastChannel();
1349  cricket::AudioSendParameters parameters;
1350  parameters.codecs.push_back(kOpusCodec);
1351  parameters.codecs[0].bitrate = 0;
1352  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 16001);
1353  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1354  EXPECT_EQ(cricket::kOpusBandwidthSwb,
1355            voe_.GetMaxEncodingBandwidth(channel_num));
1356  webrtc::CodecInst gcodec;
1357  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1358  EXPECT_STREQ("opus", gcodec.plname);
1359
1360  EXPECT_EQ(32000, gcodec.rate);
1361  parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1362  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1363  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1364  EXPECT_EQ(64000, gcodec.rate);
1365}
1366
1367// Test 24000 < maxplaybackrate triggers Opus full band mode.
1368TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateFb) {
1369  EXPECT_TRUE(SetupEngineWithSendStream());
1370  int channel_num = voe_.GetLastChannel();
1371  cricket::AudioSendParameters parameters;
1372  parameters.codecs.push_back(kOpusCodec);
1373  parameters.codecs[0].bitrate = 0;
1374  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 24001);
1375  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1376  EXPECT_EQ(cricket::kOpusBandwidthFb,
1377            voe_.GetMaxEncodingBandwidth(channel_num));
1378  webrtc::CodecInst gcodec;
1379  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1380  EXPECT_STREQ("opus", gcodec.plname);
1381
1382  EXPECT_EQ(32000, gcodec.rate);
1383  parameters.codecs[0].SetParam(cricket::kCodecParamStereo, "1");
1384  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1385  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1386  EXPECT_EQ(64000, gcodec.rate);
1387}
1388
1389// Test Opus that without maxplaybackrate, default playback rate is used.
1390TEST_F(WebRtcVoiceEngineTestFake, DefaultOpusMaxPlaybackRate) {
1391  EXPECT_TRUE(SetupEngineWithSendStream());
1392  int channel_num = voe_.GetLastChannel();
1393  cricket::AudioSendParameters parameters;
1394  parameters.codecs.push_back(kOpusCodec);
1395  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1396  EXPECT_EQ(cricket::kOpusBandwidthFb,
1397            voe_.GetMaxEncodingBandwidth(channel_num));
1398}
1399
1400// Test the with non-Opus, maxplaybackrate has no effect.
1401TEST_F(WebRtcVoiceEngineTestFake, SetNonOpusMaxPlaybackRate) {
1402  EXPECT_TRUE(SetupEngineWithSendStream());
1403  int channel_num = voe_.GetLastChannel();
1404  cricket::AudioSendParameters parameters;
1405  parameters.codecs.push_back(kIsacCodec);
1406  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 32000);
1407  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1408  EXPECT_EQ(0, voe_.GetMaxEncodingBandwidth(channel_num));
1409}
1410
1411// Test maxplaybackrate can be set on two streams.
1412TEST_F(WebRtcVoiceEngineTestFake, SetOpusMaxPlaybackRateOnTwoStreams) {
1413  EXPECT_TRUE(SetupEngineWithSendStream());
1414  int channel_num = voe_.GetLastChannel();
1415  cricket::AudioSendParameters parameters;
1416  parameters.codecs.push_back(kOpusCodec);
1417  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1418  // Default bandwidth is 24000.
1419  EXPECT_EQ(cricket::kOpusBandwidthFb,
1420            voe_.GetMaxEncodingBandwidth(channel_num));
1421
1422  parameters.codecs[0].SetParam(cricket::kCodecParamMaxPlaybackRate, 8000);
1423
1424  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1425  EXPECT_EQ(cricket::kOpusBandwidthNb,
1426            voe_.GetMaxEncodingBandwidth(channel_num));
1427
1428  channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc2));
1429  channel_num = voe_.GetLastChannel();
1430  EXPECT_EQ(cricket::kOpusBandwidthNb,
1431            voe_.GetMaxEncodingBandwidth(channel_num));
1432}
1433
1434// Test that with usedtx=0, Opus DTX is off.
1435TEST_F(WebRtcVoiceEngineTestFake, DisableOpusDtxOnOpus) {
1436  EXPECT_TRUE(SetupEngineWithSendStream());
1437  int channel_num = voe_.GetLastChannel();
1438  cricket::AudioSendParameters parameters;
1439  parameters.codecs.push_back(kOpusCodec);
1440  parameters.codecs[0].params["usedtx"] = "0";
1441  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1442  EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1443}
1444
1445// Test that with usedtx=1, Opus DTX is on.
1446TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpus) {
1447  EXPECT_TRUE(SetupEngineWithSendStream());
1448  int channel_num = voe_.GetLastChannel();
1449  cricket::AudioSendParameters parameters;
1450  parameters.codecs.push_back(kOpusCodec);
1451  parameters.codecs[0].params["usedtx"] = "1";
1452  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1453  EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1454  EXPECT_FALSE(voe_.GetVAD(channel_num));  // Opus DTX should not affect VAD.
1455}
1456
1457// Test that usedtx=1 works with stereo Opus.
1458TEST_F(WebRtcVoiceEngineTestFake, EnableOpusDtxOnOpusStereo) {
1459  EXPECT_TRUE(SetupEngineWithSendStream());
1460  int channel_num = voe_.GetLastChannel();
1461  cricket::AudioSendParameters parameters;
1462  parameters.codecs.push_back(kOpusCodec);
1463  parameters.codecs[0].params["usedtx"] = "1";
1464  parameters.codecs[0].params["stereo"] = "1";
1465  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1466  EXPECT_TRUE(voe_.GetOpusDtx(channel_num));
1467  EXPECT_FALSE(voe_.GetVAD(channel_num));   // Opus DTX should not affect VAD.
1468}
1469
1470// Test that usedtx=1 does not work with non Opus.
1471TEST_F(WebRtcVoiceEngineTestFake, CannotEnableOpusDtxOnNonOpus) {
1472  EXPECT_TRUE(SetupEngineWithSendStream());
1473  int channel_num = voe_.GetLastChannel();
1474  cricket::AudioSendParameters parameters;
1475  parameters.codecs.push_back(kIsacCodec);
1476  parameters.codecs[0].params["usedtx"] = "1";
1477  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1478  EXPECT_FALSE(voe_.GetOpusDtx(channel_num));
1479}
1480
1481// Test that we can switch back and forth between Opus and ISAC with CN.
1482TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsIsacOpusSwitching) {
1483  EXPECT_TRUE(SetupEngineWithSendStream());
1484  int channel_num = voe_.GetLastChannel();
1485  cricket::AudioSendParameters opus_parameters;
1486  opus_parameters.codecs.push_back(kOpusCodec);
1487  EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1488  webrtc::CodecInst gcodec;
1489  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1490  EXPECT_EQ(111, gcodec.pltype);
1491  EXPECT_STREQ("opus", gcodec.plname);
1492
1493  cricket::AudioSendParameters isac_parameters;
1494  isac_parameters.codecs.push_back(kIsacCodec);
1495  isac_parameters.codecs.push_back(kCn16000Codec);
1496  isac_parameters.codecs.push_back(kOpusCodec);
1497  EXPECT_TRUE(channel_->SetSendParameters(isac_parameters));
1498  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1499  EXPECT_EQ(103, gcodec.pltype);
1500  EXPECT_STREQ("ISAC", gcodec.plname);
1501
1502  EXPECT_TRUE(channel_->SetSendParameters(opus_parameters));
1503  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1504  EXPECT_EQ(111, gcodec.pltype);
1505  EXPECT_STREQ("opus", gcodec.plname);
1506}
1507
1508// Test that we handle various ways of specifying bitrate.
1509TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBitrate) {
1510  EXPECT_TRUE(SetupEngineWithSendStream());
1511  int channel_num = voe_.GetLastChannel();
1512  cricket::AudioSendParameters parameters;
1513  parameters.codecs.push_back(kIsacCodec);  // bitrate == 32000
1514  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1515  webrtc::CodecInst gcodec;
1516  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1517  EXPECT_EQ(103, gcodec.pltype);
1518  EXPECT_STREQ("ISAC", gcodec.plname);
1519  EXPECT_EQ(32000, gcodec.rate);
1520
1521  parameters.codecs[0].bitrate = 0;         // bitrate == default
1522  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1523  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1524  EXPECT_EQ(103, gcodec.pltype);
1525  EXPECT_STREQ("ISAC", gcodec.plname);
1526  EXPECT_EQ(-1, gcodec.rate);
1527
1528  parameters.codecs[0].bitrate = 28000;     // bitrate == 28000
1529  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1530  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1531  EXPECT_EQ(103, gcodec.pltype);
1532  EXPECT_STREQ("ISAC", gcodec.plname);
1533  EXPECT_EQ(28000, gcodec.rate);
1534
1535  parameters.codecs[0] = kPcmuCodec;        // bitrate == 64000
1536  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1537  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1538  EXPECT_EQ(0, gcodec.pltype);
1539  EXPECT_STREQ("PCMU", gcodec.plname);
1540  EXPECT_EQ(64000, gcodec.rate);
1541
1542  parameters.codecs[0].bitrate = 0;         // bitrate == default
1543  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1544  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1545  EXPECT_EQ(0, gcodec.pltype);
1546  EXPECT_STREQ("PCMU", gcodec.plname);
1547  EXPECT_EQ(64000, gcodec.rate);
1548
1549  parameters.codecs[0] = kOpusCodec;
1550  parameters.codecs[0].bitrate = 0;         // bitrate == default
1551  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1552  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1553  EXPECT_EQ(111, gcodec.pltype);
1554  EXPECT_STREQ("opus", gcodec.plname);
1555  EXPECT_EQ(32000, gcodec.rate);
1556}
1557
1558// Test that we could set packet size specified in kCodecParamPTime.
1559TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsPTimeAsPacketSize) {
1560  EXPECT_TRUE(SetupEngineWithSendStream());
1561  int channel_num = voe_.GetLastChannel();
1562  cricket::AudioSendParameters parameters;
1563  parameters.codecs.push_back(kOpusCodec);
1564  parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1565  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1566  webrtc::CodecInst gcodec;
1567  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1568  EXPECT_EQ(1920, gcodec.pacsize);  // Opus gets 40ms.
1569
1570  parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 5); // Below range.
1571  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1572  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1573  EXPECT_EQ(480, gcodec.pacsize);  // Opus gets 10ms.
1574
1575  parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 80); // Beyond range.
1576  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1577  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1578  EXPECT_EQ(2880, gcodec.pacsize);  // Opus gets 60ms.
1579
1580  parameters.codecs[0] = kIsacCodec;  // Also try Isac, with unsupported size.
1581  parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40); // Within range.
1582  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1583  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1584  EXPECT_EQ(480, gcodec.pacsize);  // Isac gets 30ms as the next smallest value.
1585
1586  parameters.codecs[0] = kG722CodecSdp;  // Try G722 @8kHz as negotiated in SDP.
1587  parameters.codecs[0].SetParam(cricket::kCodecParamPTime, 40);
1588  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1589  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1590  EXPECT_EQ(640, gcodec.pacsize);  // G722 gets 40ms @16kHz as defined in VoE.
1591}
1592
1593// Test that we fail if no codecs are specified.
1594TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsNoCodecs) {
1595  EXPECT_TRUE(SetupEngineWithSendStream());
1596  cricket::AudioSendParameters parameters;
1597  EXPECT_FALSE(channel_->SetSendParameters(parameters));
1598}
1599
1600// Test that we can set send codecs even with telephone-event codec as the first
1601// one on the list.
1602TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsDTMFOnTop) {
1603  EXPECT_TRUE(SetupEngineWithSendStream());
1604  int channel_num = voe_.GetLastChannel();
1605  cricket::AudioSendParameters parameters;
1606  parameters.codecs.push_back(kTelephoneEventCodec);
1607  parameters.codecs.push_back(kIsacCodec);
1608  parameters.codecs.push_back(kPcmuCodec);
1609  parameters.codecs[0].id = 98;  // DTMF
1610  parameters.codecs[1].id = 96;
1611  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1612  webrtc::CodecInst gcodec;
1613  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1614  EXPECT_EQ(96, gcodec.pltype);
1615  EXPECT_STREQ("ISAC", gcodec.plname);
1616  EXPECT_TRUE(channel_->CanInsertDtmf());
1617}
1618
1619// Test that we can set send codecs even with CN codec as the first
1620// one on the list.
1621TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNOnTop) {
1622  EXPECT_TRUE(SetupEngineWithSendStream());
1623  int channel_num = voe_.GetLastChannel();
1624  cricket::AudioSendParameters parameters;
1625  parameters.codecs.push_back(kCn16000Codec);
1626  parameters.codecs.push_back(kIsacCodec);
1627  parameters.codecs.push_back(kPcmuCodec);
1628  parameters.codecs[0].id = 98;  // wideband CN
1629  parameters.codecs[1].id = 96;
1630  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1631  webrtc::CodecInst gcodec;
1632  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1633  EXPECT_EQ(96, gcodec.pltype);
1634  EXPECT_STREQ("ISAC", gcodec.plname);
1635  EXPECT_EQ(98, voe_.GetSendCNPayloadType(channel_num, true));
1636}
1637
1638// Test that we set VAD and DTMF types correctly as caller.
1639TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCaller) {
1640  EXPECT_TRUE(SetupEngineWithSendStream());
1641  int channel_num = voe_.GetLastChannel();
1642  cricket::AudioSendParameters parameters;
1643  parameters.codecs.push_back(kIsacCodec);
1644  parameters.codecs.push_back(kPcmuCodec);
1645  // TODO(juberti): cn 32000
1646  parameters.codecs.push_back(kCn16000Codec);
1647  parameters.codecs.push_back(kCn8000Codec);
1648  parameters.codecs.push_back(kTelephoneEventCodec);
1649  parameters.codecs.push_back(kRedCodec);
1650  parameters.codecs[0].id = 96;
1651  parameters.codecs[2].id = 97;  // wideband CN
1652  parameters.codecs[4].id = 98;  // DTMF
1653  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1654  webrtc::CodecInst gcodec;
1655  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1656  EXPECT_EQ(96, gcodec.pltype);
1657  EXPECT_STREQ("ISAC", gcodec.plname);
1658  EXPECT_TRUE(voe_.GetVAD(channel_num));
1659  EXPECT_FALSE(voe_.GetRED(channel_num));
1660  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1661  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1662  EXPECT_TRUE(channel_->CanInsertDtmf());
1663}
1664
1665// Test that we set VAD and DTMF types correctly as callee.
1666TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNandDTMFAsCallee) {
1667  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1668  channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1669  EXPECT_TRUE(channel_ != nullptr);
1670
1671  cricket::AudioSendParameters parameters;
1672  parameters.codecs.push_back(kIsacCodec);
1673  parameters.codecs.push_back(kPcmuCodec);
1674  // TODO(juberti): cn 32000
1675  parameters.codecs.push_back(kCn16000Codec);
1676  parameters.codecs.push_back(kCn8000Codec);
1677  parameters.codecs.push_back(kTelephoneEventCodec);
1678  parameters.codecs.push_back(kRedCodec);
1679  parameters.codecs[0].id = 96;
1680  parameters.codecs[2].id = 97;  // wideband CN
1681  parameters.codecs[4].id = 98;  // DTMF
1682  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1683  EXPECT_TRUE(channel_->AddSendStream(
1684      cricket::StreamParams::CreateLegacy(kSsrc1)));
1685  int channel_num = voe_.GetLastChannel();
1686
1687  webrtc::CodecInst gcodec;
1688  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1689  EXPECT_EQ(96, gcodec.pltype);
1690  EXPECT_STREQ("ISAC", gcodec.plname);
1691  EXPECT_TRUE(voe_.GetVAD(channel_num));
1692  EXPECT_FALSE(voe_.GetRED(channel_num));
1693  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1694  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1695  EXPECT_TRUE(channel_->CanInsertDtmf());
1696}
1697
1698// Test that we only apply VAD if we have a CN codec that matches the
1699// send codec clockrate.
1700TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCNNoMatch) {
1701  EXPECT_TRUE(SetupEngineWithSendStream());
1702  int channel_num = voe_.GetLastChannel();
1703  cricket::AudioSendParameters parameters;
1704  // Set ISAC(16K) and CN(16K). VAD should be activated.
1705  parameters.codecs.push_back(kIsacCodec);
1706  parameters.codecs.push_back(kCn16000Codec);
1707  parameters.codecs[1].id = 97;
1708  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1709  webrtc::CodecInst gcodec;
1710  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1711  EXPECT_STREQ("ISAC", gcodec.plname);
1712  EXPECT_TRUE(voe_.GetVAD(channel_num));
1713  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1714  // Set PCMU(8K) and CN(16K). VAD should not be activated.
1715  parameters.codecs[0] = kPcmuCodec;
1716  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1717  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1718  EXPECT_STREQ("PCMU", gcodec.plname);
1719  EXPECT_FALSE(voe_.GetVAD(channel_num));
1720  // Set PCMU(8K) and CN(8K). VAD should be activated.
1721  parameters.codecs[1] = kCn8000Codec;
1722  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1723  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1724  EXPECT_STREQ("PCMU", gcodec.plname);
1725  EXPECT_TRUE(voe_.GetVAD(channel_num));
1726  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1727  // Set ISAC(16K) and CN(8K). VAD should not be activated.
1728  parameters.codecs[0] = kIsacCodec;
1729  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1730  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1731  EXPECT_STREQ("ISAC", gcodec.plname);
1732  EXPECT_FALSE(voe_.GetVAD(channel_num));
1733}
1734
1735// Test that we perform case-insensitive matching of codec names.
1736TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsCaseInsensitive) {
1737  EXPECT_TRUE(SetupEngineWithSendStream());
1738  int channel_num = voe_.GetLastChannel();
1739  cricket::AudioSendParameters parameters;
1740  parameters.codecs.push_back(kIsacCodec);
1741  parameters.codecs.push_back(kPcmuCodec);
1742  parameters.codecs.push_back(kCn16000Codec);
1743  parameters.codecs.push_back(kCn8000Codec);
1744  parameters.codecs.push_back(kTelephoneEventCodec);
1745  parameters.codecs.push_back(kRedCodec);
1746  parameters.codecs[0].name = "iSaC";
1747  parameters.codecs[0].id = 96;
1748  parameters.codecs[2].id = 97;  // wideband CN
1749  parameters.codecs[4].id = 98;  // DTMF
1750  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1751  webrtc::CodecInst gcodec;
1752  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1753  EXPECT_EQ(96, gcodec.pltype);
1754  EXPECT_STREQ("ISAC", gcodec.plname);
1755  EXPECT_TRUE(voe_.GetVAD(channel_num));
1756  EXPECT_FALSE(voe_.GetRED(channel_num));
1757  EXPECT_EQ(13, voe_.GetSendCNPayloadType(channel_num, false));
1758  EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
1759  EXPECT_TRUE(channel_->CanInsertDtmf());
1760}
1761
1762// Test that we set up RED correctly as caller.
1763TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCaller) {
1764  EXPECT_TRUE(SetupEngineWithSendStream());
1765  int channel_num = voe_.GetLastChannel();
1766  cricket::AudioSendParameters parameters;
1767  parameters.codecs.push_back(kRedCodec);
1768  parameters.codecs.push_back(kIsacCodec);
1769  parameters.codecs.push_back(kPcmuCodec);
1770  parameters.codecs[0].id = 127;
1771  parameters.codecs[0].params[""] = "96/96";
1772  parameters.codecs[1].id = 96;
1773  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1774  webrtc::CodecInst gcodec;
1775  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1776  EXPECT_EQ(96, gcodec.pltype);
1777  EXPECT_STREQ("ISAC", gcodec.plname);
1778  EXPECT_TRUE(voe_.GetRED(channel_num));
1779  EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1780}
1781
1782// Test that we set up RED correctly as callee.
1783TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDAsCallee) {
1784  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
1785  channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
1786  EXPECT_TRUE(channel_ != nullptr);
1787
1788  cricket::AudioSendParameters parameters;
1789  parameters.codecs.push_back(kRedCodec);
1790  parameters.codecs.push_back(kIsacCodec);
1791  parameters.codecs.push_back(kPcmuCodec);
1792  parameters.codecs[0].id = 127;
1793  parameters.codecs[0].params[""] = "96/96";
1794  parameters.codecs[1].id = 96;
1795  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1796  EXPECT_TRUE(channel_->AddSendStream(
1797      cricket::StreamParams::CreateLegacy(kSsrc1)));
1798  int channel_num = voe_.GetLastChannel();
1799  webrtc::CodecInst gcodec;
1800  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1801  EXPECT_EQ(96, gcodec.pltype);
1802  EXPECT_STREQ("ISAC", gcodec.plname);
1803  EXPECT_TRUE(voe_.GetRED(channel_num));
1804  EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1805}
1806
1807// Test that we set up RED correctly if params are omitted.
1808TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsREDNoParams) {
1809  EXPECT_TRUE(SetupEngineWithSendStream());
1810  int channel_num = voe_.GetLastChannel();
1811  cricket::AudioSendParameters parameters;
1812  parameters.codecs.push_back(kRedCodec);
1813  parameters.codecs.push_back(kIsacCodec);
1814  parameters.codecs.push_back(kPcmuCodec);
1815  parameters.codecs[0].id = 127;
1816  parameters.codecs[1].id = 96;
1817  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1818  webrtc::CodecInst gcodec;
1819  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1820  EXPECT_EQ(96, gcodec.pltype);
1821  EXPECT_STREQ("ISAC", gcodec.plname);
1822  EXPECT_TRUE(voe_.GetRED(channel_num));
1823  EXPECT_EQ(127, voe_.GetSendREDPayloadType(channel_num));
1824}
1825
1826// Test that we ignore RED if the parameters aren't named the way we expect.
1827TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED1) {
1828  EXPECT_TRUE(SetupEngineWithSendStream());
1829  int channel_num = voe_.GetLastChannel();
1830  cricket::AudioSendParameters parameters;
1831  parameters.codecs.push_back(kRedCodec);
1832  parameters.codecs.push_back(kIsacCodec);
1833  parameters.codecs.push_back(kPcmuCodec);
1834  parameters.codecs[0].id = 127;
1835  parameters.codecs[0].params["ABC"] = "96/96";
1836  parameters.codecs[1].id = 96;
1837  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1838  webrtc::CodecInst gcodec;
1839  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1840  EXPECT_EQ(96, gcodec.pltype);
1841  EXPECT_STREQ("ISAC", gcodec.plname);
1842  EXPECT_FALSE(voe_.GetRED(channel_num));
1843}
1844
1845// Test that we ignore RED if it uses different primary/secondary encoding.
1846TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED2) {
1847  EXPECT_TRUE(SetupEngineWithSendStream());
1848  int channel_num = voe_.GetLastChannel();
1849  cricket::AudioSendParameters parameters;
1850  parameters.codecs.push_back(kRedCodec);
1851  parameters.codecs.push_back(kIsacCodec);
1852  parameters.codecs.push_back(kPcmuCodec);
1853  parameters.codecs[0].id = 127;
1854  parameters.codecs[0].params[""] = "96/0";
1855  parameters.codecs[1].id = 96;
1856  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1857  webrtc::CodecInst gcodec;
1858  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1859  EXPECT_EQ(96, gcodec.pltype);
1860  EXPECT_STREQ("ISAC", gcodec.plname);
1861  EXPECT_FALSE(voe_.GetRED(channel_num));
1862}
1863
1864// Test that we ignore RED if it uses more than 2 encodings.
1865TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED3) {
1866  EXPECT_TRUE(SetupEngineWithSendStream());
1867  int channel_num = voe_.GetLastChannel();
1868  cricket::AudioSendParameters parameters;
1869  parameters.codecs.push_back(kRedCodec);
1870  parameters.codecs.push_back(kIsacCodec);
1871  parameters.codecs.push_back(kPcmuCodec);
1872  parameters.codecs[0].id = 127;
1873  parameters.codecs[0].params[""] = "96/96/96";
1874  parameters.codecs[1].id = 96;
1875  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1876  webrtc::CodecInst gcodec;
1877  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1878  EXPECT_EQ(96, gcodec.pltype);
1879  EXPECT_STREQ("ISAC", gcodec.plname);
1880  EXPECT_FALSE(voe_.GetRED(channel_num));
1881}
1882
1883// Test that we ignore RED if it has bogus codec ids.
1884TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED4) {
1885  EXPECT_TRUE(SetupEngineWithSendStream());
1886  int channel_num = voe_.GetLastChannel();
1887  cricket::AudioSendParameters parameters;
1888  parameters.codecs.push_back(kRedCodec);
1889  parameters.codecs.push_back(kIsacCodec);
1890  parameters.codecs.push_back(kPcmuCodec);
1891  parameters.codecs[0].id = 127;
1892  parameters.codecs[0].params[""] = "ABC/ABC";
1893  parameters.codecs[1].id = 96;
1894  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1895  webrtc::CodecInst gcodec;
1896  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1897  EXPECT_EQ(96, gcodec.pltype);
1898  EXPECT_STREQ("ISAC", gcodec.plname);
1899  EXPECT_FALSE(voe_.GetRED(channel_num));
1900}
1901
1902// Test that we ignore RED if it refers to a codec that is not present.
1903TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
1904  EXPECT_TRUE(SetupEngineWithSendStream());
1905  int channel_num = voe_.GetLastChannel();
1906  cricket::AudioSendParameters parameters;
1907  parameters.codecs.push_back(kRedCodec);
1908  parameters.codecs.push_back(kIsacCodec);
1909  parameters.codecs.push_back(kPcmuCodec);
1910  parameters.codecs[0].id = 127;
1911  parameters.codecs[0].params[""] = "97/97";
1912  parameters.codecs[1].id = 96;
1913  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1914  webrtc::CodecInst gcodec;
1915  EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
1916  EXPECT_EQ(96, gcodec.pltype);
1917  EXPECT_STREQ("ISAC", gcodec.plname);
1918  EXPECT_FALSE(voe_.GetRED(channel_num));
1919}
1920
1921// Test support for audio level header extension.
1922TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1923  TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1924}
1925TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1926  TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1927}
1928
1929// Test support for absolute send time header extension.
1930TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1931  TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1932}
1933TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1934  TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1935}
1936
1937// Test that we can create a channel and start sending on it.
1938TEST_F(WebRtcVoiceEngineTestFake, Send) {
1939  EXPECT_TRUE(SetupEngineWithSendStream());
1940  int channel_num = voe_.GetLastChannel();
1941  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1942  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1943  EXPECT_TRUE(voe_.GetSend(channel_num));
1944  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
1945  EXPECT_FALSE(voe_.GetSend(channel_num));
1946}
1947
1948// Test that we can create a channel and start playing out on it.
1949TEST_F(WebRtcVoiceEngineTestFake, Playout) {
1950  EXPECT_TRUE(SetupEngineWithRecvStream());
1951  int channel_num = voe_.GetLastChannel();
1952  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1953  EXPECT_TRUE(channel_->SetPlayout(true));
1954  EXPECT_TRUE(voe_.GetPlayout(channel_num));
1955  EXPECT_TRUE(channel_->SetPlayout(false));
1956  EXPECT_FALSE(voe_.GetPlayout(channel_num));
1957}
1958
1959// Test that we can add and remove send streams.
1960TEST_F(WebRtcVoiceEngineTestFake, CreateAndDeleteMultipleSendStreams) {
1961  SetupForMultiSendStream();
1962
1963  // Set the global state for sending.
1964  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
1965
1966  for (uint32_t ssrc : kSsrcs4) {
1967    EXPECT_TRUE(channel_->AddSendStream(
1968        cricket::StreamParams::CreateLegacy(ssrc)));
1969    // Verify that we are in a sending state for all the created streams.
1970    EXPECT_TRUE(voe_.GetSend(GetSendStreamConfig(ssrc).voe_channel_id));
1971  }
1972  EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioSendStreams().size());
1973
1974  // Delete the send streams.
1975  for (uint32_t ssrc : kSsrcs4) {
1976    EXPECT_TRUE(channel_->RemoveSendStream(ssrc));
1977    EXPECT_FALSE(call_.GetAudioSendStream(ssrc));
1978    EXPECT_FALSE(channel_->RemoveSendStream(ssrc));
1979  }
1980  EXPECT_EQ(0u, call_.GetAudioSendStreams().size());
1981}
1982
1983// Test SetSendCodecs correctly configure the codecs in all send streams.
1984TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsWithMultipleSendStreams) {
1985  SetupForMultiSendStream();
1986
1987  // Create send streams.
1988  for (uint32_t ssrc : kSsrcs4) {
1989    EXPECT_TRUE(channel_->AddSendStream(
1990        cricket::StreamParams::CreateLegacy(ssrc)));
1991  }
1992
1993  cricket::AudioSendParameters parameters;
1994  // Set ISAC(16K) and CN(16K). VAD should be activated.
1995  parameters.codecs.push_back(kIsacCodec);
1996  parameters.codecs.push_back(kCn16000Codec);
1997  parameters.codecs[1].id = 97;
1998  EXPECT_TRUE(channel_->SetSendParameters(parameters));
1999
2000  // Verify ISAC and VAD are corrected configured on all send channels.
2001  webrtc::CodecInst gcodec;
2002  for (uint32_t ssrc : kSsrcs4) {
2003    int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2004    EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2005    EXPECT_STREQ("ISAC", gcodec.plname);
2006    EXPECT_TRUE(voe_.GetVAD(channel_num));
2007    EXPECT_EQ(97, voe_.GetSendCNPayloadType(channel_num, true));
2008  }
2009
2010  // Change to PCMU(8K) and CN(16K). VAD should not be activated.
2011  parameters.codecs[0] = kPcmuCodec;
2012  EXPECT_TRUE(channel_->SetSendParameters(parameters));
2013  for (uint32_t ssrc : kSsrcs4) {
2014    int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2015    EXPECT_EQ(0, voe_.GetSendCodec(channel_num, gcodec));
2016    EXPECT_STREQ("PCMU", gcodec.plname);
2017    EXPECT_FALSE(voe_.GetVAD(channel_num));
2018  }
2019}
2020
2021// Test we can SetSend on all send streams correctly.
2022TEST_F(WebRtcVoiceEngineTestFake, SetSendWithMultipleSendStreams) {
2023  SetupForMultiSendStream();
2024
2025  // Create the send channels and they should be a SEND_NOTHING date.
2026  for (uint32_t ssrc : kSsrcs4) {
2027    EXPECT_TRUE(channel_->AddSendStream(
2028        cricket::StreamParams::CreateLegacy(ssrc)));
2029    int channel_num = voe_.GetLastChannel();
2030    EXPECT_FALSE(voe_.GetSend(channel_num));
2031  }
2032
2033  // Set the global state for starting sending.
2034  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2035  for (uint32_t ssrc : kSsrcs4) {
2036    // Verify that we are in a sending state for all the send streams.
2037    int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2038    EXPECT_TRUE(voe_.GetSend(channel_num));
2039  }
2040
2041  // Set the global state for stopping sending.
2042  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2043  for (uint32_t ssrc : kSsrcs4) {
2044    // Verify that we are in a stop state for all the send streams.
2045    int channel_num = GetSendStreamConfig(ssrc).voe_channel_id;
2046    EXPECT_FALSE(voe_.GetSend(channel_num));
2047  }
2048}
2049
2050// Test we can set the correct statistics on all send streams.
2051TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
2052  SetupForMultiSendStream();
2053
2054  // Create send streams.
2055  for (uint32_t ssrc : kSsrcs4) {
2056    EXPECT_TRUE(channel_->AddSendStream(
2057        cricket::StreamParams::CreateLegacy(ssrc)));
2058  }
2059  SetAudioSendStreamStats();
2060
2061  // Create a receive stream to check that none of the send streams end up in
2062  // the receive stream stats.
2063  EXPECT_TRUE(channel_->AddRecvStream(
2064      cricket::StreamParams::CreateLegacy(kSsrc2)));
2065  // We need send codec to be set to get all stats.
2066  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2067  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2068
2069  // Check stats for the added streams.
2070  {
2071    cricket::VoiceMediaInfo info;
2072    EXPECT_EQ(true, channel_->GetStats(&info));
2073
2074    // We have added 4 send streams. We should see empty stats for all.
2075    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2076    for (const auto& sender : info.senders) {
2077      VerifyVoiceSenderInfo(sender, false);
2078    }
2079
2080    // We have added one receive stream. We should see empty stats.
2081    EXPECT_EQ(info.receivers.size(), 1u);
2082    EXPECT_EQ(info.receivers[0].ssrc(), 0);
2083  }
2084
2085  // Remove the kSsrc2 stream. No receiver stats.
2086  {
2087    cricket::VoiceMediaInfo info;
2088    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2089    EXPECT_EQ(true, channel_->GetStats(&info));
2090    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2091    EXPECT_EQ(0u, info.receivers.size());
2092  }
2093
2094  // Deliver a new packet - a default receive stream should be created and we
2095  // should see stats again.
2096  {
2097    cricket::VoiceMediaInfo info;
2098    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2099    SetAudioReceiveStreamStats();
2100    EXPECT_EQ(true, channel_->GetStats(&info));
2101    EXPECT_EQ(static_cast<size_t>(arraysize(kSsrcs4)), info.senders.size());
2102    EXPECT_EQ(1u, info.receivers.size());
2103    VerifyVoiceReceiverInfo(info.receivers[0]);
2104  }
2105}
2106
2107// Test that we can add and remove receive streams, and do proper send/playout.
2108// We can receive on multiple streams while sending one stream.
2109TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {
2110  EXPECT_TRUE(SetupEngineWithSendStream());
2111  int channel_num1 = voe_.GetLastChannel();
2112
2113  // Start playout without a receive stream.
2114  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2115  EXPECT_TRUE(channel_->SetPlayout(true));
2116  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2117
2118  // Adding another stream should enable playout on the new stream only.
2119  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2120  int channel_num2 = voe_.GetLastChannel();
2121  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2122  EXPECT_TRUE(voe_.GetSend(channel_num1));
2123  EXPECT_FALSE(voe_.GetSend(channel_num2));
2124
2125  // Make sure only the new stream is played out.
2126  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2127  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2128
2129  // Adding yet another stream should have stream 2 and 3 enabled for playout.
2130  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2131  int channel_num3 = voe_.GetLastChannel();
2132  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2133  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2134  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2135  EXPECT_FALSE(voe_.GetSend(channel_num3));
2136
2137  // Stop sending.
2138  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2139  EXPECT_FALSE(voe_.GetSend(channel_num1));
2140  EXPECT_FALSE(voe_.GetSend(channel_num2));
2141  EXPECT_FALSE(voe_.GetSend(channel_num3));
2142
2143  // Stop playout.
2144  EXPECT_TRUE(channel_->SetPlayout(false));
2145  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2146  EXPECT_FALSE(voe_.GetPlayout(channel_num2));
2147  EXPECT_FALSE(voe_.GetPlayout(channel_num3));
2148
2149  // Restart playout and make sure only recv streams are played out.
2150  EXPECT_TRUE(channel_->SetPlayout(true));
2151  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2152  EXPECT_TRUE(voe_.GetPlayout(channel_num2));
2153  EXPECT_TRUE(voe_.GetPlayout(channel_num3));
2154
2155  // Now remove the recv streams and verify that the send stream doesn't play.
2156  EXPECT_TRUE(channel_->RemoveRecvStream(3));
2157  EXPECT_TRUE(channel_->RemoveRecvStream(2));
2158  EXPECT_FALSE(voe_.GetPlayout(channel_num1));
2159}
2160
2161// Test that we can create a channel configured for Codian bridges,
2162// and start sending on it.
2163TEST_F(WebRtcVoiceEngineTestFake, CodianSend) {
2164  EXPECT_TRUE(SetupEngineWithSendStream());
2165  cricket::AudioOptions options_adjust_agc;
2166  options_adjust_agc.adjust_agc_delta = rtc::Optional<int>(-10);
2167  int channel_num = voe_.GetLastChannel();
2168  webrtc::AgcConfig agc_config;
2169  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2170  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2171  send_parameters_.options = options_adjust_agc;
2172  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2173  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2174  EXPECT_TRUE(voe_.GetSend(channel_num));
2175  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2176  EXPECT_EQ(agc_config.targetLeveldBOv, 10);  // level was attenuated
2177  EXPECT_TRUE(channel_->SetSend(cricket::SEND_NOTHING));
2178  EXPECT_FALSE(voe_.GetSend(channel_num));
2179  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2180}
2181
2182TEST_F(WebRtcVoiceEngineTestFake, TxAgcConfigViaOptions) {
2183  EXPECT_TRUE(SetupEngineWithSendStream());
2184  webrtc::AgcConfig agc_config;
2185  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2186  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2187  send_parameters_.options.tx_agc_target_dbov = rtc::Optional<uint16_t>(3);
2188  send_parameters_.options.tx_agc_digital_compression_gain =
2189      rtc::Optional<uint16_t>(9);
2190  send_parameters_.options.tx_agc_limiter = rtc::Optional<bool>(true);
2191  send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2192  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2193  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2194  EXPECT_EQ(3, agc_config.targetLeveldBOv);
2195  EXPECT_EQ(9, agc_config.digitalCompressionGaindB);
2196  EXPECT_TRUE(agc_config.limiterEnable);
2197
2198  // Check interaction with adjust_agc_delta. Both should be respected, for
2199  // backwards compatibility.
2200  send_parameters_.options.adjust_agc_delta = rtc::Optional<int>(-10);
2201  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2202  EXPECT_EQ(0, voe_.GetAgcConfig(agc_config));
2203  EXPECT_EQ(13, agc_config.targetLeveldBOv);
2204}
2205
2206TEST_F(WebRtcVoiceEngineTestFake, SampleRatesViaOptions) {
2207  EXPECT_TRUE(SetupEngineWithSendStream());
2208  send_parameters_.options.recording_sample_rate =
2209      rtc::Optional<uint32_t>(48000);
2210  send_parameters_.options.playout_sample_rate = rtc::Optional<uint32_t>(44100);
2211  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2212
2213  unsigned int recording_sample_rate, playout_sample_rate;
2214  EXPECT_EQ(0, voe_.RecordingSampleRate(&recording_sample_rate));
2215  EXPECT_EQ(0, voe_.PlayoutSampleRate(&playout_sample_rate));
2216  EXPECT_EQ(48000u, recording_sample_rate);
2217  EXPECT_EQ(44100u, playout_sample_rate);
2218}
2219
2220// Test that we can set the outgoing SSRC properly.
2221// SSRC is set in SetupEngine by calling AddSendStream.
2222TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2223  EXPECT_TRUE(SetupEngineWithSendStream());
2224  EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2225}
2226
2227TEST_F(WebRtcVoiceEngineTestFake, GetStats) {
2228  // Setup. We need send codec to be set to get all stats.
2229  EXPECT_TRUE(SetupEngineWithSendStream());
2230  SetAudioSendStreamStats();
2231  // SetupEngineWithSendStream adds a send stream with kSsrc1, so the receive
2232  // stream has to use a different SSRC.
2233  EXPECT_TRUE(channel_->AddRecvStream(
2234      cricket::StreamParams::CreateLegacy(kSsrc2)));
2235  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2236  EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2237
2238  // Check stats for the added streams.
2239  {
2240    cricket::VoiceMediaInfo info;
2241    EXPECT_EQ(true, channel_->GetStats(&info));
2242
2243    // We have added one send stream. We should see the stats we've set.
2244    EXPECT_EQ(1u, info.senders.size());
2245    VerifyVoiceSenderInfo(info.senders[0], false);
2246    // We have added one receive stream. We should see empty stats.
2247    EXPECT_EQ(info.receivers.size(), 1u);
2248    EXPECT_EQ(info.receivers[0].ssrc(), 0);
2249  }
2250
2251  // Start sending - this affects some reported stats.
2252  {
2253    cricket::VoiceMediaInfo info;
2254    EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2255    EXPECT_EQ(true, channel_->GetStats(&info));
2256    VerifyVoiceSenderInfo(info.senders[0], true);
2257  }
2258
2259  // Remove the kSsrc2 stream. No receiver stats.
2260  {
2261    cricket::VoiceMediaInfo info;
2262    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc2));
2263    EXPECT_EQ(true, channel_->GetStats(&info));
2264    EXPECT_EQ(1u, info.senders.size());
2265    EXPECT_EQ(0u, info.receivers.size());
2266  }
2267
2268  // Deliver a new packet - a default receive stream should be created and we
2269  // should see stats again.
2270  {
2271    cricket::VoiceMediaInfo info;
2272    DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2273    SetAudioReceiveStreamStats();
2274    EXPECT_EQ(true, channel_->GetStats(&info));
2275    EXPECT_EQ(1u, info.senders.size());
2276    EXPECT_EQ(1u, info.receivers.size());
2277    VerifyVoiceReceiverInfo(info.receivers[0]);
2278  }
2279}
2280
2281// Test that we can set the outgoing SSRC properly with multiple streams.
2282// SSRC is set in SetupEngine by calling AddSendStream.
2283TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcWithMultipleStreams) {
2284  EXPECT_TRUE(SetupEngineWithSendStream());
2285  EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2286  EXPECT_TRUE(channel_->AddRecvStream(
2287      cricket::StreamParams::CreateLegacy(kSsrc2)));
2288  EXPECT_EQ(kSsrc1, GetRecvStreamConfig(kSsrc2).rtp.local_ssrc);
2289}
2290
2291// Test that the local SSRC is the same on sending and receiving channels if the
2292// receive channel is created before the send channel.
2293TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
2294  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2295  channel_ = engine_.CreateChannel(&call_, cricket::AudioOptions());
2296
2297  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2298  int receive_channel_num = voe_.GetLastChannel();
2299  EXPECT_TRUE(channel_->AddSendStream(
2300      cricket::StreamParams::CreateLegacy(1234)));
2301
2302  EXPECT_TRUE(call_.GetAudioSendStream(1234));
2303  EXPECT_EQ(1234U, voe_.GetLocalSSRC(receive_channel_num));
2304}
2305
2306// Test that we can properly receive packets.
2307TEST_F(WebRtcVoiceEngineTestFake, Recv) {
2308  EXPECT_TRUE(SetupEngine());
2309  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2310  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2311  int channel_num = voe_.GetLastChannel();
2312  EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2313}
2314
2315// Test that we can properly receive packets on multiple streams.
2316TEST_F(WebRtcVoiceEngineTestFake, RecvWithMultipleStreams) {
2317  EXPECT_TRUE(SetupEngine());
2318  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2319  int channel_num1 = voe_.GetLastChannel();
2320  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2321  int channel_num2 = voe_.GetLastChannel();
2322  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2323  int channel_num3 = voe_.GetLastChannel();
2324  // Create packets with the right SSRCs.
2325  char packets[4][sizeof(kPcmuFrame)];
2326  for (size_t i = 0; i < arraysize(packets); ++i) {
2327    memcpy(packets[i], kPcmuFrame, sizeof(kPcmuFrame));
2328    rtc::SetBE32(packets[i] + 8, static_cast<uint32_t>(i));
2329  }
2330  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2331  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2332  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2333
2334  DeliverPacket(packets[0], sizeof(packets[0]));
2335  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2336  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2337  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2338
2339  DeliverPacket(packets[1], sizeof(packets[1]));
2340  EXPECT_TRUE(voe_.CheckPacket(channel_num1, packets[1], sizeof(packets[1])));
2341  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2342  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2343
2344  DeliverPacket(packets[2], sizeof(packets[2]));
2345  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2346  EXPECT_TRUE(voe_.CheckPacket(channel_num2, packets[2], sizeof(packets[2])));
2347  EXPECT_TRUE(voe_.CheckNoPacket(channel_num3));
2348
2349  DeliverPacket(packets[3], sizeof(packets[3]));
2350  EXPECT_TRUE(voe_.CheckNoPacket(channel_num1));
2351  EXPECT_TRUE(voe_.CheckNoPacket(channel_num2));
2352  EXPECT_TRUE(voe_.CheckPacket(channel_num3, packets[3], sizeof(packets[3])));
2353
2354  EXPECT_TRUE(channel_->RemoveRecvStream(3));
2355  EXPECT_TRUE(channel_->RemoveRecvStream(2));
2356  EXPECT_TRUE(channel_->RemoveRecvStream(1));
2357}
2358
2359// Test that receiving on an unsignalled stream works (default channel will be
2360// created).
2361TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalled) {
2362  EXPECT_TRUE(SetupEngine());
2363  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2364  int channel_num = voe_.GetLastChannel();
2365  EXPECT_TRUE(voe_.CheckPacket(channel_num, kPcmuFrame, sizeof(kPcmuFrame)));
2366}
2367
2368// Test that receiving on an unsignalled stream works (default channel will be
2369// created), and that packets will be forwarded to the default channel
2370// regardless of their SSRCs.
2371TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledWithSsrcSwitch) {
2372  EXPECT_TRUE(SetupEngine());
2373  char packet[sizeof(kPcmuFrame)];
2374  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2375
2376  // Note that the first unknown SSRC cannot be 0, because we only support
2377  // creating receive streams for SSRC!=0.
2378  DeliverPacket(packet, sizeof(packet));
2379  int channel_num = voe_.GetLastChannel();
2380  EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2381  // Once we have the default channel, SSRC==0 will be ok.
2382  for (uint32_t ssrc = 0; ssrc < 10; ++ssrc) {
2383    rtc::SetBE32(&packet[8], ssrc);
2384    DeliverPacket(packet, sizeof(packet));
2385    EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2386  }
2387}
2388
2389// Test that a default channel is created even after a signalled stream has been
2390// added, and that this stream will get any packets for unknown SSRCs.
2391TEST_F(WebRtcVoiceEngineTestFake, RecvUnsignalledAfterSignalled) {
2392  EXPECT_TRUE(SetupEngine());
2393  char packet[sizeof(kPcmuFrame)];
2394  memcpy(packet, kPcmuFrame, sizeof(kPcmuFrame));
2395
2396  // Add a known stream, send packet and verify we got it.
2397  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2398  int signalled_channel_num = voe_.GetLastChannel();
2399  DeliverPacket(packet, sizeof(packet));
2400  EXPECT_TRUE(voe_.CheckPacket(signalled_channel_num, packet, sizeof(packet)));
2401
2402  // Note that the first unknown SSRC cannot be 0, because we only support
2403  // creating receive streams for SSRC!=0.
2404  rtc::SetBE32(&packet[8], 7011);
2405  DeliverPacket(packet, sizeof(packet));
2406  int channel_num = voe_.GetLastChannel();
2407  EXPECT_NE(channel_num, signalled_channel_num);
2408  EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2409  // Once we have the default channel, SSRC==0 will be ok.
2410  for (uint32_t ssrc = 0; ssrc < 20; ssrc += 2) {
2411    rtc::SetBE32(&packet[8], ssrc);
2412    DeliverPacket(packet, sizeof(packet));
2413    EXPECT_TRUE(voe_.CheckPacket(channel_num, packet, sizeof(packet)));
2414  }
2415}
2416
2417// Test that we properly handle failures to add a receive stream.
2418TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamFail) {
2419  EXPECT_TRUE(SetupEngine());
2420  voe_.set_fail_create_channel(true);
2421  EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2422}
2423
2424// Test that we properly handle failures to add a send stream.
2425TEST_F(WebRtcVoiceEngineTestFake, AddSendStreamFail) {
2426  EXPECT_TRUE(SetupEngine());
2427  voe_.set_fail_create_channel(true);
2428  EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2429}
2430
2431// Test that AddRecvStream creates new stream.
2432TEST_F(WebRtcVoiceEngineTestFake, AddRecvStream) {
2433  EXPECT_TRUE(SetupEngineWithRecvStream());
2434  int channel_num = voe_.GetLastChannel();
2435  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2436  EXPECT_NE(channel_num, voe_.GetLastChannel());
2437}
2438
2439// Test that after adding a recv stream, we do not decode more codecs than
2440// those previously passed into SetRecvCodecs.
2441TEST_F(WebRtcVoiceEngineTestFake, AddRecvStreamUnsupportedCodec) {
2442  EXPECT_TRUE(SetupEngineWithSendStream());
2443  cricket::AudioRecvParameters parameters;
2444  parameters.codecs.push_back(kIsacCodec);
2445  parameters.codecs.push_back(kPcmuCodec);
2446  EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2447  EXPECT_TRUE(channel_->AddRecvStream(
2448      cricket::StreamParams::CreateLegacy(kSsrc1)));
2449  int channel_num2 = voe_.GetLastChannel();
2450  webrtc::CodecInst gcodec;
2451  rtc::strcpyn(gcodec.plname, arraysize(gcodec.plname), "opus");
2452  gcodec.plfreq = 48000;
2453  gcodec.channels = 2;
2454  EXPECT_EQ(-1, voe_.GetRecPayloadType(channel_num2, gcodec));
2455}
2456
2457// Test that we properly clean up any streams that were added, even if
2458// not explicitly removed.
2459TEST_F(WebRtcVoiceEngineTestFake, StreamCleanup) {
2460  EXPECT_TRUE(SetupEngineWithSendStream());
2461  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2462  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2463  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2464  EXPECT_EQ(3, voe_.GetNumChannels());  // default channel + 2 added
2465  delete channel_;
2466  channel_ = NULL;
2467  EXPECT_EQ(0, voe_.GetNumChannels());
2468}
2469
2470TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2471  EXPECT_TRUE(SetupEngineWithSendStream());
2472  EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2473}
2474
2475TEST_F(WebRtcVoiceEngineTestFake, TestNoLeakingWhenAddRecvStreamFail) {
2476  EXPECT_TRUE(SetupEngine());
2477  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2478  // Manually delete channel to simulate a failure.
2479  int channel = voe_.GetLastChannel();
2480  EXPECT_EQ(0, voe_.DeleteChannel(channel));
2481  // Add recv stream 2 should work.
2482  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2483  int new_channel = voe_.GetLastChannel();
2484  EXPECT_NE(channel, new_channel);
2485  // The last created channel is deleted too.
2486  EXPECT_EQ(0, voe_.DeleteChannel(new_channel));
2487}
2488
2489// Test the InsertDtmf on default send stream as caller.
2490TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2491  TestInsertDtmf(0, true);
2492}
2493
2494// Test the InsertDtmf on default send stream as callee
2495TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2496  TestInsertDtmf(0, false);
2497}
2498
2499// Test the InsertDtmf on specified send stream as caller.
2500TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2501  TestInsertDtmf(kSsrc1, true);
2502}
2503
2504// Test the InsertDtmf on specified send stream as callee.
2505TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2506  TestInsertDtmf(kSsrc1, false);
2507}
2508
2509TEST_F(WebRtcVoiceEngineTestFake, TestSetPlayoutError) {
2510  EXPECT_TRUE(SetupEngineWithSendStream());
2511  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2512  EXPECT_TRUE(channel_->SetSend(cricket::SEND_MICROPHONE));
2513  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2514  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
2515  EXPECT_TRUE(channel_->SetPlayout(true));
2516  voe_.set_playout_fail_channel(voe_.GetLastChannel() - 1);
2517  EXPECT_TRUE(channel_->SetPlayout(false));
2518  EXPECT_FALSE(channel_->SetPlayout(true));
2519}
2520
2521TEST_F(WebRtcVoiceEngineTestFake, SetAudioOptions) {
2522  EXPECT_TRUE(SetupEngineWithSendStream());
2523
2524  bool ec_enabled;
2525  webrtc::EcModes ec_mode;
2526  webrtc::AecmModes aecm_mode;
2527  bool cng_enabled;
2528  bool agc_enabled;
2529  webrtc::AgcModes agc_mode;
2530  webrtc::AgcConfig agc_config;
2531  bool ns_enabled;
2532  webrtc::NsModes ns_mode;
2533  bool highpass_filter_enabled;
2534  bool stereo_swapping_enabled;
2535  bool typing_detection_enabled;
2536  voe_.GetEcStatus(ec_enabled, ec_mode);
2537  voe_.GetAecmMode(aecm_mode, cng_enabled);
2538  voe_.GetAgcStatus(agc_enabled, agc_mode);
2539  voe_.GetAgcConfig(agc_config);
2540  voe_.GetNsStatus(ns_enabled, ns_mode);
2541  highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2542  stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2543  voe_.GetTypingDetectionStatus(typing_detection_enabled);
2544  EXPECT_TRUE(ec_enabled);
2545  EXPECT_TRUE(voe_.ec_metrics_enabled());
2546  EXPECT_FALSE(cng_enabled);
2547  EXPECT_TRUE(agc_enabled);
2548  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2549  EXPECT_TRUE(ns_enabled);
2550  EXPECT_TRUE(highpass_filter_enabled);
2551  EXPECT_FALSE(stereo_swapping_enabled);
2552  EXPECT_TRUE(typing_detection_enabled);
2553  EXPECT_EQ(ec_mode, webrtc::kEcConference);
2554  EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2555  EXPECT_EQ(50, voe_.GetNetEqCapacity());
2556  EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2557
2558  // Nothing set in AudioOptions, so everything should be as default.
2559  send_parameters_.options = cricket::AudioOptions();
2560  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2561  voe_.GetEcStatus(ec_enabled, ec_mode);
2562  voe_.GetAecmMode(aecm_mode, cng_enabled);
2563  voe_.GetAgcStatus(agc_enabled, agc_mode);
2564  voe_.GetAgcConfig(agc_config);
2565  voe_.GetNsStatus(ns_enabled, ns_mode);
2566  highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2567  stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2568  voe_.GetTypingDetectionStatus(typing_detection_enabled);
2569  EXPECT_TRUE(ec_enabled);
2570  EXPECT_TRUE(voe_.ec_metrics_enabled());
2571  EXPECT_FALSE(cng_enabled);
2572  EXPECT_TRUE(agc_enabled);
2573  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2574  EXPECT_TRUE(ns_enabled);
2575  EXPECT_TRUE(highpass_filter_enabled);
2576  EXPECT_FALSE(stereo_swapping_enabled);
2577  EXPECT_TRUE(typing_detection_enabled);
2578  EXPECT_EQ(ec_mode, webrtc::kEcConference);
2579  EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2580  EXPECT_EQ(50, voe_.GetNetEqCapacity());
2581  EXPECT_FALSE(voe_.GetNetEqFastAccelerate());
2582
2583  // Turn echo cancellation off
2584  send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2585  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2586  voe_.GetEcStatus(ec_enabled, ec_mode);
2587  EXPECT_FALSE(ec_enabled);
2588
2589  // Turn echo cancellation back on, with settings, and make sure
2590  // nothing else changed.
2591  send_parameters_.options.echo_cancellation = rtc::Optional<bool>(true);
2592  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2593  voe_.GetEcStatus(ec_enabled, ec_mode);
2594  voe_.GetAecmMode(aecm_mode, cng_enabled);
2595  voe_.GetAgcStatus(agc_enabled, agc_mode);
2596  voe_.GetAgcConfig(agc_config);
2597  voe_.GetNsStatus(ns_enabled, ns_mode);
2598  highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2599  stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2600  voe_.GetTypingDetectionStatus(typing_detection_enabled);
2601  EXPECT_TRUE(ec_enabled);
2602  EXPECT_TRUE(voe_.ec_metrics_enabled());
2603  EXPECT_TRUE(agc_enabled);
2604  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2605  EXPECT_TRUE(ns_enabled);
2606  EXPECT_TRUE(highpass_filter_enabled);
2607  EXPECT_FALSE(stereo_swapping_enabled);
2608  EXPECT_TRUE(typing_detection_enabled);
2609  EXPECT_EQ(ec_mode, webrtc::kEcConference);
2610  EXPECT_EQ(ns_mode, webrtc::kNsHighSuppression);
2611
2612  // Turn on delay agnostic aec and make sure nothing change w.r.t. echo
2613  // control.
2614  send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2615  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2616  voe_.GetEcStatus(ec_enabled, ec_mode);
2617  voe_.GetAecmMode(aecm_mode, cng_enabled);
2618  EXPECT_TRUE(ec_enabled);
2619  EXPECT_TRUE(voe_.ec_metrics_enabled());
2620  EXPECT_EQ(ec_mode, webrtc::kEcConference);
2621
2622  // Turn off echo cancellation and delay agnostic aec.
2623  send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(false);
2624  send_parameters_.options.extended_filter_aec = rtc::Optional<bool>(false);
2625  send_parameters_.options.echo_cancellation = rtc::Optional<bool>(false);
2626  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2627  voe_.GetEcStatus(ec_enabled, ec_mode);
2628  EXPECT_FALSE(ec_enabled);
2629  // Turning delay agnostic aec back on should also turn on echo cancellation.
2630  send_parameters_.options.delay_agnostic_aec = rtc::Optional<bool>(true);
2631  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2632  voe_.GetEcStatus(ec_enabled, ec_mode);
2633  EXPECT_TRUE(ec_enabled);
2634  EXPECT_TRUE(voe_.ec_metrics_enabled());
2635  EXPECT_EQ(ec_mode, webrtc::kEcConference);
2636
2637  // Turn off AGC
2638  send_parameters_.options.auto_gain_control = rtc::Optional<bool>(false);
2639  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2640  voe_.GetAgcStatus(agc_enabled, agc_mode);
2641  EXPECT_FALSE(agc_enabled);
2642
2643  // Turn AGC back on
2644  send_parameters_.options.auto_gain_control = rtc::Optional<bool>(true);
2645  send_parameters_.options.adjust_agc_delta = rtc::Optional<int>();
2646  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2647  voe_.GetAgcStatus(agc_enabled, agc_mode);
2648  EXPECT_TRUE(agc_enabled);
2649  voe_.GetAgcConfig(agc_config);
2650  EXPECT_EQ(0, agc_config.targetLeveldBOv);
2651
2652  // Turn off other options (and stereo swapping on).
2653  send_parameters_.options.noise_suppression = rtc::Optional<bool>(false);
2654  send_parameters_.options.highpass_filter = rtc::Optional<bool>(false);
2655  send_parameters_.options.typing_detection = rtc::Optional<bool>(false);
2656  send_parameters_.options.stereo_swapping = rtc::Optional<bool>(true);
2657  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2658  voe_.GetNsStatus(ns_enabled, ns_mode);
2659  highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2660  stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2661  voe_.GetTypingDetectionStatus(typing_detection_enabled);
2662  EXPECT_FALSE(ns_enabled);
2663  EXPECT_FALSE(highpass_filter_enabled);
2664  EXPECT_FALSE(typing_detection_enabled);
2665  EXPECT_TRUE(stereo_swapping_enabled);
2666
2667  // Set options again to ensure it has no impact.
2668  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2669  voe_.GetEcStatus(ec_enabled, ec_mode);
2670  voe_.GetNsStatus(ns_enabled, ns_mode);
2671  EXPECT_TRUE(ec_enabled);
2672  EXPECT_EQ(webrtc::kEcConference, ec_mode);
2673  EXPECT_FALSE(ns_enabled);
2674  EXPECT_EQ(webrtc::kNsHighSuppression, ns_mode);
2675}
2676
2677TEST_F(WebRtcVoiceEngineTestFake, DefaultOptions) {
2678  EXPECT_TRUE(SetupEngineWithSendStream());
2679
2680  bool ec_enabled;
2681  webrtc::EcModes ec_mode;
2682  bool agc_enabled;
2683  webrtc::AgcModes agc_mode;
2684  bool ns_enabled;
2685  webrtc::NsModes ns_mode;
2686  bool highpass_filter_enabled;
2687  bool stereo_swapping_enabled;
2688  bool typing_detection_enabled;
2689
2690  voe_.GetEcStatus(ec_enabled, ec_mode);
2691  voe_.GetAgcStatus(agc_enabled, agc_mode);
2692  voe_.GetNsStatus(ns_enabled, ns_mode);
2693  highpass_filter_enabled = voe_.IsHighPassFilterEnabled();
2694  stereo_swapping_enabled = voe_.IsStereoChannelSwappingEnabled();
2695  voe_.GetTypingDetectionStatus(typing_detection_enabled);
2696  EXPECT_TRUE(ec_enabled);
2697  EXPECT_TRUE(agc_enabled);
2698  EXPECT_TRUE(ns_enabled);
2699  EXPECT_TRUE(highpass_filter_enabled);
2700  EXPECT_TRUE(typing_detection_enabled);
2701  EXPECT_FALSE(stereo_swapping_enabled);
2702}
2703
2704TEST_F(WebRtcVoiceEngineTestFake, InitDoesNotOverwriteDefaultAgcConfig) {
2705  webrtc::AgcConfig set_config = {0};
2706  set_config.targetLeveldBOv = 3;
2707  set_config.digitalCompressionGaindB = 9;
2708  set_config.limiterEnable = true;
2709  EXPECT_EQ(0, voe_.SetAgcConfig(set_config));
2710  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2711
2712  webrtc::AgcConfig config = {0};
2713  EXPECT_EQ(0, voe_.GetAgcConfig(config));
2714  EXPECT_EQ(set_config.targetLeveldBOv, config.targetLeveldBOv);
2715  EXPECT_EQ(set_config.digitalCompressionGaindB,
2716            config.digitalCompressionGaindB);
2717  EXPECT_EQ(set_config.limiterEnable, config.limiterEnable);
2718}
2719
2720TEST_F(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
2721  EXPECT_TRUE(SetupEngineWithSendStream());
2722  rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
2723      static_cast<cricket::WebRtcVoiceMediaChannel*>(
2724          engine_.CreateChannel(&call_, cricket::AudioOptions())));
2725  rtc::scoped_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
2726      static_cast<cricket::WebRtcVoiceMediaChannel*>(
2727          engine_.CreateChannel(&call_, cricket::AudioOptions())));
2728
2729  // Have to add a stream to make SetSend work.
2730  cricket::StreamParams stream1;
2731  stream1.ssrcs.push_back(1);
2732  channel1->AddSendStream(stream1);
2733  cricket::StreamParams stream2;
2734  stream2.ssrcs.push_back(2);
2735  channel2->AddSendStream(stream2);
2736
2737  // AEC and AGC and NS
2738  cricket::AudioSendParameters parameters_options_all = send_parameters_;
2739  parameters_options_all.options.echo_cancellation = rtc::Optional<bool>(true);
2740  parameters_options_all.options.auto_gain_control = rtc::Optional<bool>(true);
2741  parameters_options_all.options.noise_suppression = rtc::Optional<bool>(true);
2742  ASSERT_TRUE(channel1->SetSendParameters(parameters_options_all));
2743  EXPECT_EQ(parameters_options_all.options, channel1->options());
2744  ASSERT_TRUE(channel2->SetSendParameters(parameters_options_all));
2745  EXPECT_EQ(parameters_options_all.options, channel2->options());
2746
2747  // unset NS
2748  cricket::AudioSendParameters parameters_options_no_ns = send_parameters_;
2749  parameters_options_no_ns.options.noise_suppression =
2750      rtc::Optional<bool>(false);
2751  ASSERT_TRUE(channel1->SetSendParameters(parameters_options_no_ns));
2752  cricket::AudioOptions expected_options = parameters_options_all.options;
2753  expected_options.echo_cancellation = rtc::Optional<bool>(true);
2754  expected_options.auto_gain_control = rtc::Optional<bool>(true);
2755  expected_options.noise_suppression = rtc::Optional<bool>(false);
2756  EXPECT_EQ(expected_options, channel1->options());
2757
2758  // unset AGC
2759  cricket::AudioSendParameters parameters_options_no_agc = send_parameters_;
2760  parameters_options_no_agc.options.auto_gain_control =
2761      rtc::Optional<bool>(false);
2762  ASSERT_TRUE(channel2->SetSendParameters(parameters_options_no_agc));
2763  expected_options.echo_cancellation = rtc::Optional<bool>(true);
2764  expected_options.auto_gain_control = rtc::Optional<bool>(false);
2765  expected_options.noise_suppression = rtc::Optional<bool>(true);
2766  EXPECT_EQ(expected_options, channel2->options());
2767
2768  ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2769  bool ec_enabled;
2770  webrtc::EcModes ec_mode;
2771  bool agc_enabled;
2772  webrtc::AgcModes agc_mode;
2773  bool ns_enabled;
2774  webrtc::NsModes ns_mode;
2775  voe_.GetEcStatus(ec_enabled, ec_mode);
2776  voe_.GetAgcStatus(agc_enabled, agc_mode);
2777  voe_.GetNsStatus(ns_enabled, ns_mode);
2778  EXPECT_TRUE(ec_enabled);
2779  EXPECT_TRUE(agc_enabled);
2780  EXPECT_TRUE(ns_enabled);
2781
2782  channel1->SetSend(cricket::SEND_MICROPHONE);
2783  voe_.GetEcStatus(ec_enabled, ec_mode);
2784  voe_.GetAgcStatus(agc_enabled, agc_mode);
2785  voe_.GetNsStatus(ns_enabled, ns_mode);
2786  EXPECT_TRUE(ec_enabled);
2787  EXPECT_TRUE(agc_enabled);
2788  EXPECT_FALSE(ns_enabled);
2789
2790  channel2->SetSend(cricket::SEND_MICROPHONE);
2791  voe_.GetEcStatus(ec_enabled, ec_mode);
2792  voe_.GetAgcStatus(agc_enabled, agc_mode);
2793  voe_.GetNsStatus(ns_enabled, ns_mode);
2794  EXPECT_TRUE(ec_enabled);
2795  EXPECT_FALSE(agc_enabled);
2796  EXPECT_TRUE(ns_enabled);
2797
2798  // Make sure settings take effect while we are sending.
2799  ASSERT_TRUE(channel_->SetSendParameters(parameters_options_all));
2800  cricket::AudioSendParameters parameters_options_no_agc_nor_ns =
2801      send_parameters_;
2802  parameters_options_no_agc_nor_ns.options.auto_gain_control =
2803      rtc::Optional<bool>(false);
2804  parameters_options_no_agc_nor_ns.options.noise_suppression =
2805      rtc::Optional<bool>(false);
2806  channel2->SetSend(cricket::SEND_MICROPHONE);
2807  channel2->SetSendParameters(parameters_options_no_agc_nor_ns);
2808  expected_options.echo_cancellation = rtc::Optional<bool>(true);
2809  expected_options.auto_gain_control = rtc::Optional<bool>(false);
2810  expected_options.noise_suppression = rtc::Optional<bool>(false);
2811  EXPECT_EQ(expected_options, channel2->options());
2812  voe_.GetEcStatus(ec_enabled, ec_mode);
2813  voe_.GetAgcStatus(agc_enabled, agc_mode);
2814  voe_.GetNsStatus(ns_enabled, ns_mode);
2815  EXPECT_TRUE(ec_enabled);
2816  EXPECT_FALSE(agc_enabled);
2817  EXPECT_FALSE(ns_enabled);
2818}
2819
2820// This test verifies DSCP settings are properly applied on voice media channel.
2821TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
2822  EXPECT_TRUE(SetupEngineWithSendStream());
2823  rtc::scoped_ptr<cricket::VoiceMediaChannel> channel(
2824      engine_.CreateChannel(&call_, cricket::AudioOptions()));
2825  rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2826      new cricket::FakeNetworkInterface);
2827  channel->SetInterface(network_interface.get());
2828  cricket::AudioSendParameters parameters = send_parameters_;
2829  parameters.options.dscp = rtc::Optional<bool>(true);
2830  EXPECT_TRUE(channel->SetSendParameters(parameters));
2831  EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2832  // Verify previous value is not modified if dscp option is not set.
2833  EXPECT_TRUE(channel->SetSendParameters(send_parameters_));
2834  EXPECT_EQ(rtc::DSCP_EF, network_interface->dscp());
2835  parameters.options.dscp = rtc::Optional<bool>(false);
2836  EXPECT_TRUE(channel->SetSendParameters(parameters));
2837  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2838}
2839
2840TEST_F(WebRtcVoiceEngineTestFake, TestGetReceiveChannelId) {
2841  EXPECT_TRUE(SetupEngine());
2842  cricket::WebRtcVoiceMediaChannel* media_channel =
2843        static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2844  EXPECT_EQ(-1, media_channel->GetReceiveChannelId(0));
2845  EXPECT_TRUE(channel_->AddRecvStream(
2846      cricket::StreamParams::CreateLegacy(kSsrc1)));
2847  int channel_id = voe_.GetLastChannel();
2848  EXPECT_EQ(channel_id, media_channel->GetReceiveChannelId(kSsrc1));
2849  EXPECT_EQ(-1, media_channel->GetReceiveChannelId(kSsrc2));
2850  EXPECT_TRUE(channel_->AddRecvStream(
2851      cricket::StreamParams::CreateLegacy(kSsrc2)));
2852  int channel_id2 = voe_.GetLastChannel();
2853  EXPECT_EQ(channel_id2, media_channel->GetReceiveChannelId(kSsrc2));
2854}
2855
2856TEST_F(WebRtcVoiceEngineTestFake, TestGetSendChannelId) {
2857  EXPECT_TRUE(SetupEngine());
2858  cricket::WebRtcVoiceMediaChannel* media_channel =
2859        static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2860  EXPECT_EQ(-1, media_channel->GetSendChannelId(0));
2861  EXPECT_TRUE(channel_->AddSendStream(
2862      cricket::StreamParams::CreateLegacy(kSsrc1)));
2863  int channel_id = voe_.GetLastChannel();
2864  EXPECT_EQ(channel_id, media_channel->GetSendChannelId(kSsrc1));
2865  EXPECT_EQ(-1, media_channel->GetSendChannelId(kSsrc2));
2866  EXPECT_TRUE(channel_->AddSendStream(
2867      cricket::StreamParams::CreateLegacy(kSsrc2)));
2868  int channel_id2 = voe_.GetLastChannel();
2869  EXPECT_EQ(channel_id2, media_channel->GetSendChannelId(kSsrc2));
2870}
2871
2872TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
2873  EXPECT_TRUE(SetupEngine());
2874  EXPECT_FALSE(channel_->SetOutputVolume(kSsrc2, 0.5));
2875  cricket::StreamParams stream;
2876  stream.ssrcs.push_back(kSsrc2);
2877  EXPECT_TRUE(channel_->AddRecvStream(stream));
2878  int channel_id = voe_.GetLastChannel();
2879  EXPECT_TRUE(channel_->SetOutputVolume(kSsrc2, 3));
2880  float scale = 0;
2881  EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2882  EXPECT_DOUBLE_EQ(3, scale);
2883}
2884
2885TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolumeDefaultRecvStream) {
2886  EXPECT_TRUE(SetupEngine());
2887  EXPECT_TRUE(channel_->SetOutputVolume(0, 2));
2888  DeliverPacket(kPcmuFrame, sizeof(kPcmuFrame));
2889  int channel_id = voe_.GetLastChannel();
2890  float scale = 0;
2891  EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2892  EXPECT_DOUBLE_EQ(2, scale);
2893  EXPECT_TRUE(channel_->SetOutputVolume(0, 3));
2894  EXPECT_EQ(0, voe_.GetChannelOutputVolumeScaling(channel_id, scale));
2895  EXPECT_DOUBLE_EQ(3, scale);
2896}
2897
2898TEST_F(WebRtcVoiceEngineTestFake, SetsSyncGroupFromSyncLabel) {
2899  const uint32_t kAudioSsrc = 123;
2900  const std::string kSyncLabel = "AvSyncLabel";
2901
2902  EXPECT_TRUE(SetupEngineWithSendStream());
2903  cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kAudioSsrc);
2904  sp.sync_label = kSyncLabel;
2905  // Creating two channels to make sure that sync label is set properly for both
2906  // the default voice channel and following ones.
2907  EXPECT_TRUE(channel_->AddRecvStream(sp));
2908  sp.ssrcs[0] += 1;
2909  EXPECT_TRUE(channel_->AddRecvStream(sp));
2910
2911  ASSERT_EQ(2, call_.GetAudioReceiveStreams().size());
2912  EXPECT_EQ(kSyncLabel,
2913            call_.GetAudioReceiveStream(kAudioSsrc)->GetConfig().sync_group)
2914      << "SyncGroup should be set based on sync_label";
2915  EXPECT_EQ(kSyncLabel,
2916            call_.GetAudioReceiveStream(kAudioSsrc + 1)->GetConfig().sync_group)
2917      << "SyncGroup should be set based on sync_label";
2918}
2919
2920TEST_F(WebRtcVoiceEngineTestFake, CanChangeCombinedBweOption) {
2921  // Test that changing the combined_audio_video_bwe option results in the
2922  // expected state changes on an associated Call.
2923  std::vector<uint32_t> ssrcs;
2924  ssrcs.push_back(223);
2925  ssrcs.push_back(224);
2926
2927  EXPECT_TRUE(SetupEngineWithSendStream());
2928  cricket::WebRtcVoiceMediaChannel* media_channel =
2929      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2930  for (uint32_t ssrc : ssrcs) {
2931    EXPECT_TRUE(media_channel->AddRecvStream(
2932        cricket::StreamParams::CreateLegacy(ssrc)));
2933  }
2934  EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2935
2936  // Combined BWE should be disabled.
2937  for (uint32_t ssrc : ssrcs) {
2938    const auto* s = call_.GetAudioReceiveStream(ssrc);
2939    EXPECT_NE(nullptr, s);
2940    EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2941  }
2942
2943  // Enable combined BWE option - now it should be set up.
2944  send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2945  EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2946  for (uint32_t ssrc : ssrcs) {
2947    const auto* s = call_.GetAudioReceiveStream(ssrc);
2948    EXPECT_NE(nullptr, s);
2949    EXPECT_EQ(true, s->GetConfig().combined_audio_video_bwe);
2950  }
2951
2952  // Disable combined BWE option - should be disabled again.
2953  send_parameters_.options.combined_audio_video_bwe =
2954      rtc::Optional<bool>(false);
2955  EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2956  for (uint32_t ssrc : ssrcs) {
2957    const auto* s = call_.GetAudioReceiveStream(ssrc);
2958    EXPECT_NE(nullptr, s);
2959    EXPECT_FALSE(s->GetConfig().combined_audio_video_bwe);
2960  }
2961
2962  EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
2963}
2964
2965TEST_F(WebRtcVoiceEngineTestFake, ConfigureCombinedBweForNewRecvStreams) {
2966  // Test that adding receive streams after enabling combined bandwidth
2967  // estimation will correctly configure each channel.
2968  EXPECT_TRUE(SetupEngineWithSendStream());
2969  cricket::WebRtcVoiceMediaChannel* media_channel =
2970      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2971  send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2972  EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2973
2974  for (uint32_t ssrc : kSsrcs4) {
2975    EXPECT_TRUE(media_channel->AddRecvStream(
2976        cricket::StreamParams::CreateLegacy(ssrc)));
2977    EXPECT_NE(nullptr, call_.GetAudioReceiveStream(ssrc));
2978  }
2979  EXPECT_EQ(arraysize(kSsrcs4), call_.GetAudioReceiveStreams().size());
2980}
2981
2982// TODO(solenberg): Remove, once recv streams are configured through Call.
2983//                  (This is then covered by TestSetRecvRtpHeaderExtensions.)
2984TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
2985  // Test that setting the header extensions results in the expected state
2986  // changes on an associated Call.
2987  std::vector<uint32_t> ssrcs;
2988  ssrcs.push_back(223);
2989  ssrcs.push_back(224);
2990
2991  EXPECT_TRUE(SetupEngineWithSendStream());
2992  cricket::WebRtcVoiceMediaChannel* media_channel =
2993      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
2994  send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
2995  EXPECT_TRUE(media_channel->SetSendParameters(send_parameters_));
2996  for (uint32_t ssrc : ssrcs) {
2997    EXPECT_TRUE(media_channel->AddRecvStream(
2998        cricket::StreamParams::CreateLegacy(ssrc)));
2999  }
3000
3001  // Combined BWE should be set up, but with no configured extensions.
3002  EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3003  for (uint32_t ssrc : ssrcs) {
3004    const auto* s = call_.GetAudioReceiveStream(ssrc);
3005    EXPECT_NE(nullptr, s);
3006    EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3007  }
3008
3009  // Set up receive extensions.
3010  cricket::RtpCapabilities capabilities = engine_.GetCapabilities();
3011  cricket::AudioRecvParameters recv_parameters;
3012  recv_parameters.extensions = capabilities.header_extensions;
3013  channel_->SetRecvParameters(recv_parameters);
3014  EXPECT_EQ(2, call_.GetAudioReceiveStreams().size());
3015  for (uint32_t ssrc : ssrcs) {
3016    const auto* s = call_.GetAudioReceiveStream(ssrc);
3017    EXPECT_NE(nullptr, s);
3018    const auto& s_exts = s->GetConfig().rtp.extensions;
3019    EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
3020    for (const auto& e_ext : capabilities.header_extensions) {
3021      for (const auto& s_ext : s_exts) {
3022        if (e_ext.id == s_ext.id) {
3023          EXPECT_EQ(e_ext.uri, s_ext.name);
3024        }
3025      }
3026    }
3027  }
3028
3029  // Disable receive extensions.
3030  channel_->SetRecvParameters(cricket::AudioRecvParameters());
3031  for (uint32_t ssrc : ssrcs) {
3032    const auto* s = call_.GetAudioReceiveStream(ssrc);
3033    EXPECT_NE(nullptr, s);
3034    EXPECT_EQ(0, s->GetConfig().rtp.extensions.size());
3035  }
3036}
3037
3038TEST_F(WebRtcVoiceEngineTestFake, DeliverAudioPacket_Call) {
3039  // Test that packets are forwarded to the Call when configured accordingly.
3040  const uint32_t kAudioSsrc = 1;
3041  rtc::Buffer kPcmuPacket(kPcmuFrame, sizeof(kPcmuFrame));
3042  static const unsigned char kRtcp[] = {
3043    0x80, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
3044    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
3045    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3046    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
3047  };
3048  rtc::Buffer kRtcpPacket(kRtcp, sizeof(kRtcp));
3049
3050  EXPECT_TRUE(SetupEngineWithSendStream());
3051  cricket::WebRtcVoiceMediaChannel* media_channel =
3052      static_cast<cricket::WebRtcVoiceMediaChannel*>(channel_);
3053  send_parameters_.options.combined_audio_video_bwe = rtc::Optional<bool>(true);
3054  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3055  EXPECT_TRUE(media_channel->AddRecvStream(
3056      cricket::StreamParams::CreateLegacy(kAudioSsrc)));
3057
3058  EXPECT_EQ(1, call_.GetAudioReceiveStreams().size());
3059  const cricket::FakeAudioReceiveStream* s =
3060      call_.GetAudioReceiveStream(kAudioSsrc);
3061  EXPECT_EQ(0, s->received_packets());
3062  channel_->OnPacketReceived(&kPcmuPacket, rtc::PacketTime());
3063  EXPECT_EQ(1, s->received_packets());
3064  channel_->OnRtcpReceived(&kRtcpPacket, rtc::PacketTime());
3065  EXPECT_EQ(2, s->received_packets());
3066}
3067
3068// All receive channels should be associated with the first send channel,
3069// since they do not send RTCP SR.
3070TEST_F(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel) {
3071  EXPECT_TRUE(SetupEngineWithSendStream());
3072  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3073  int default_channel = voe_.GetLastChannel();
3074  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3075  int recv_ch = voe_.GetLastChannel();
3076  EXPECT_NE(recv_ch, default_channel);
3077  EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3078  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3079  EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3080  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(3)));
3081  recv_ch = voe_.GetLastChannel();
3082  EXPECT_NE(recv_ch, default_channel);
3083  EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), default_channel);
3084}
3085
3086TEST_F(WebRtcVoiceEngineTestFake, AssociateChannelResetUponDeleteChannnel) {
3087  EXPECT_TRUE(SetupEngineWithSendStream());
3088  EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3089
3090  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3091  int recv_ch = voe_.GetLastChannel();
3092
3093  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
3094  int send_ch = voe_.GetLastChannel();
3095
3096  // Manually associate |recv_ch| to |send_ch|. This test is to verify a
3097  // deleting logic, i.e., deleting |send_ch| will reset the associate send
3098  // channel of |recv_ch|.This is not a common case, since, normally, only the
3099  // default channel can be associated. However, the default is not deletable.
3100  // So we force the |recv_ch| to associate with a non-default channel.
3101  EXPECT_EQ(0, voe_.AssociateSendChannel(recv_ch, send_ch));
3102  EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), send_ch);
3103
3104  EXPECT_TRUE(channel_->RemoveSendStream(2));
3105  EXPECT_EQ(voe_.GetAssociateSendChannel(recv_ch), -1);
3106}
3107
3108// Tests that the library initializes and shuts down properly.
3109TEST(WebRtcVoiceEngineTest, StartupShutdown) {
3110  cricket::WebRtcVoiceEngine engine;
3111  EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3112  rtc::scoped_ptr<webrtc::Call> call(
3113      webrtc::Call::Create(webrtc::Call::Config()));
3114  cricket::VoiceMediaChannel* channel =
3115      engine.CreateChannel(call.get(), cricket::AudioOptions());
3116  EXPECT_TRUE(channel != nullptr);
3117  delete channel;
3118  engine.Terminate();
3119
3120  // Reinit to catch regression where VoiceEngineObserver reference is lost
3121  EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3122  engine.Terminate();
3123}
3124
3125// Tests that the library is configured with the codecs we want.
3126TEST(WebRtcVoiceEngineTest, HasCorrectCodecs) {
3127  // Check codecs by name.
3128  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3129      cricket::AudioCodec(96, "OPUS", 48000, 0, 2, 0), nullptr));
3130  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3131      cricket::AudioCodec(96, "ISAC", 16000, 0, 1, 0), nullptr));
3132  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3133      cricket::AudioCodec(96, "ISAC", 32000, 0, 1, 0), nullptr));
3134  // Check that name matching is case-insensitive.
3135  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3136      cricket::AudioCodec(96, "ILBC", 8000, 0, 1, 0), nullptr));
3137  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3138      cricket::AudioCodec(96, "iLBC", 8000, 0, 1, 0), nullptr));
3139  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3140      cricket::AudioCodec(96, "PCMU", 8000, 0, 1, 0), nullptr));
3141  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3142      cricket::AudioCodec(96, "PCMA", 8000, 0, 1, 0), nullptr));
3143  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3144      cricket::AudioCodec(96, "G722", 8000, 0, 1, 0), nullptr));
3145  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3146      cricket::AudioCodec(96, "red", 8000, 0, 1, 0), nullptr));
3147  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3148      cricket::AudioCodec(96, "CN", 32000, 0, 1, 0), nullptr));
3149  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3150      cricket::AudioCodec(96, "CN", 16000, 0, 1, 0), nullptr));
3151  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3152      cricket::AudioCodec(96, "CN", 8000, 0, 1, 0), nullptr));
3153  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3154      cricket::AudioCodec(96, "telephone-event", 8000, 0, 1, 0), nullptr));
3155  // Check codecs with an id by id.
3156  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3157      cricket::AudioCodec(0, "", 8000, 0, 1, 0), nullptr));   // PCMU
3158  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3159      cricket::AudioCodec(8, "", 8000, 0, 1, 0), nullptr));   // PCMA
3160  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3161      cricket::AudioCodec(9, "", 8000, 0, 1, 0), nullptr));  // G722
3162  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3163      cricket::AudioCodec(13, "", 8000, 0, 1, 0), nullptr));  // CN
3164  // Check sample/bitrate matching.
3165  EXPECT_TRUE(cricket::WebRtcVoiceEngine::ToCodecInst(
3166      cricket::AudioCodec(0, "PCMU", 8000, 64000, 1, 0), nullptr));
3167  // Check that bad codecs fail.
3168  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3169      cricket::AudioCodec(99, "ABCD", 0, 0, 1, 0), nullptr));
3170  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3171      cricket::AudioCodec(88, "", 0, 0, 1, 0), nullptr));
3172  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3173      cricket::AudioCodec(0, "", 0, 0, 2, 0), nullptr));
3174  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3175      cricket::AudioCodec(0, "", 5000, 0, 1, 0), nullptr));
3176  EXPECT_FALSE(cricket::WebRtcVoiceEngine::ToCodecInst(
3177      cricket::AudioCodec(0, "", 0, 5000, 1, 0), nullptr));
3178
3179  // Verify the payload id of common audio codecs, including CN, ISAC, and G722.
3180  cricket::WebRtcVoiceEngine engine;
3181  for (std::vector<cricket::AudioCodec>::const_iterator it =
3182      engine.codecs().begin(); it != engine.codecs().end(); ++it) {
3183    if (it->name == "CN" && it->clockrate == 16000) {
3184      EXPECT_EQ(105, it->id);
3185    } else if (it->name == "CN" && it->clockrate == 32000) {
3186      EXPECT_EQ(106, it->id);
3187    } else if (it->name == "ISAC" && it->clockrate == 16000) {
3188      EXPECT_EQ(103, it->id);
3189    } else if (it->name == "ISAC" && it->clockrate == 32000) {
3190      EXPECT_EQ(104, it->id);
3191    } else if (it->name == "G722" && it->clockrate == 8000) {
3192      EXPECT_EQ(9, it->id);
3193    } else if (it->name == "telephone-event") {
3194      EXPECT_EQ(126, it->id);
3195    } else if (it->name == "red") {
3196      EXPECT_EQ(127, it->id);
3197    } else if (it->name == "opus") {
3198      EXPECT_EQ(111, it->id);
3199      ASSERT_TRUE(it->params.find("minptime") != it->params.end());
3200      EXPECT_EQ("10", it->params.find("minptime")->second);
3201      ASSERT_TRUE(it->params.find("maxptime") != it->params.end());
3202      EXPECT_EQ("60", it->params.find("maxptime")->second);
3203      ASSERT_TRUE(it->params.find("useinbandfec") != it->params.end());
3204      EXPECT_EQ("1", it->params.find("useinbandfec")->second);
3205    }
3206  }
3207  engine.Terminate();
3208}
3209
3210// Tests that VoE supports at least 32 channels
3211TEST(WebRtcVoiceEngineTest, Has32Channels) {
3212  cricket::WebRtcVoiceEngine engine;
3213  EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3214  rtc::scoped_ptr<webrtc::Call> call(
3215      webrtc::Call::Create(webrtc::Call::Config()));
3216
3217  cricket::VoiceMediaChannel* channels[32];
3218  int num_channels = 0;
3219  while (num_channels < arraysize(channels)) {
3220    cricket::VoiceMediaChannel* channel =
3221        engine.CreateChannel(call.get(), cricket::AudioOptions());
3222    if (!channel)
3223      break;
3224    channels[num_channels++] = channel;
3225  }
3226
3227  int expected = arraysize(channels);
3228  EXPECT_EQ(expected, num_channels);
3229
3230  while (num_channels > 0) {
3231    delete channels[--num_channels];
3232  }
3233  engine.Terminate();
3234}
3235
3236// Test that we set our preferred codecs properly.
3237TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
3238  cricket::WebRtcVoiceEngine engine;
3239  EXPECT_TRUE(engine.Init(rtc::Thread::Current()));
3240  rtc::scoped_ptr<webrtc::Call> call(
3241      webrtc::Call::Create(webrtc::Call::Config()));
3242  cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::AudioOptions(),
3243                                           call.get());
3244  cricket::AudioRecvParameters parameters;
3245  parameters.codecs = engine.codecs();
3246  EXPECT_TRUE(channel.SetRecvParameters(parameters));
3247}
3248