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 
42 using cricket::kRtpAudioLevelHeaderExtension;
43 using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
44 
45 namespace {
46 
47 const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1, 0);
48 const cricket::AudioCodec kIsacCodec(103, "ISAC", 16000, 32000, 1, 0);
49 const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 64000, 2, 0);
50 const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1, 0);
51 const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1, 0);
52 const cricket::AudioCodec kRedCodec(117, "red", 8000, 0, 1, 0);
53 const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1, 0);
54 const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1, 0);
55 const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000, 0,
56                                                1, 0);
57 const uint32_t kSsrc1 = 0x99;
58 const uint32_t kSsrc2 = 0x98;
59 const uint32_t kSsrcs4[] = { 1, 2, 3, 4 };
60 
61 class FakeVoEWrapper : public cricket::VoEWrapper {
62  public:
FakeVoEWrapper(cricket::FakeWebRtcVoiceEngine * engine)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 
75 class WebRtcVoiceEngineTestFake : public testing::Test {
76  public:
WebRtcVoiceEngineTestFake()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   }
SetupEngine()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   }
SetupEngineWithRecvStream()91   bool SetupEngineWithRecvStream() {
92     if (!SetupEngine()) {
93       return false;
94     }
95     return channel_->AddRecvStream(
96         cricket::StreamParams::CreateLegacy(kSsrc1));
97   }
SetupEngineWithSendStream()98   bool SetupEngineWithSendStream() {
99     if (!SetupEngine()) {
100       return false;
101     }
102     return channel_->AddSendStream(
103         cricket::StreamParams::CreateLegacy(kSsrc1));
104   }
SetupForMultiSendStream()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   }
DeliverPacket(const void * data,int len)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   }
TearDown()117   void TearDown() override {
118     delete channel_;
119     engine_.Terminate();
120   }
121 
GetSendStream(uint32_t ssrc)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 
GetSendStreamConfig(uint32_t ssrc)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 
GetRecvStreamConfig(uint32_t ssrc)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 
TestInsertDtmf(uint32_t ssrc,bool caller)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.
TestSendBandwidth(const cricket::AudioCodec & codec,int max_bitrate,bool expected_result,int expected_bitrate)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 
TestSetSendRtpHeaderExtensions(const std::string & ext)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 
TestSetRecvRtpHeaderExtensions(const std::string & ext)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 
GetAudioSendStreamStats() const284   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   }
SetAudioSendStreamStats()304   void SetAudioSendStreamStats() {
305     for (auto* s : call_.GetAudioSendStreams()) {
306       s->SetStats(GetAudioSendStreamStats());
307     }
308   }
VerifyVoiceSenderInfo(const cricket::VoiceSenderInfo & info,bool is_sending)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 
GetAudioReceiveStreamStats() const332   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   }
SetAudioReceiveStreamStats()360   void SetAudioReceiveStreamStats() {
361     for (auto* s : call_.GetAudioReceiveStreams()) {
362       s->SetStats(GetAudioReceiveStreamStats());
363     }
364   }
VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo & info)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".
TEST_F(WebRtcVoiceEngineTestFake,StartupShutdown)405 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,CreateChannel)414 TEST_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
TEST_F(WebRtcVoiceEngineTestFake,CodecPreference)422 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,FindCodec)438 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecs)474 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsUnsupportedCodec)501 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsDuplicatePayloadType)510 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpusNoStereo)520 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpus0Stereo)542 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithOpus1Stereo)565 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWithMultipleStreams)587 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsAfterAddingStreams)614 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetRecvCodecsWhilePlaying)632 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvCodecsWhilePlaying)649 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetSendBandwidthAuto)666 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthMultiRateAsCaller)683 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthFixedRateAsCaller)697 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthMultiRateAsCallee)713 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetMaxSendBandwidthCbr)733 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecs)755 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,DontResetSetSendCodec)780 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecG722)797 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBadClockrate)811 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad0ChannelsNoStereo)821 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad0Channels1Stereo)831 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpus1ChannelNoStereo)842 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad1Channel0Stereo)852 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusBad1Channel1Stereo)863 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0BitrateNoStereo)875 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0Bitrate0Stereo)891 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodXBitrate0Stereo)908 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGood0Bitrate1Stereo)934 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodXBitrate1Stereo)951 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrateNoStereo)977 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrate0Stereo)995 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrateNoParameters)1012 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusGoodNBitrate1Stereo)1028 TEST_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
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusMaxAverageBitrate)1046 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackAsCaller)1073 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackAsCallee)1087 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecEnableNackRecvStreams)1105 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecDisableNack)1123 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecDisableNackRecvStreams)1141 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamEnableNack)1163 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecNoOpusFec)1184 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusDisableFec)1194 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusEnableFec)1211 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecOpusEnableFecStereo)1228 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecIsacNoFec)1246 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecIsacWithParamNoFec)1256 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,ChangeOpusFecStatus)1267 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateNb)1280 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateMb)1302 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateWb)1324 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateSwb)1346 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateFb)1368 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,DefaultOpusMaxPlaybackRate)1390 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetNonOpusMaxPlaybackRate)1401 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetOpusMaxPlaybackRateOnTwoStreams)1412 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,DisableOpusDtxOnOpus)1435 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,EnableOpusDtxOnOpus)1446 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,EnableOpusDtxOnOpusStereo)1458 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,CannotEnableOpusDtxOnNonOpus)1471 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsIsacOpusSwitching)1482 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBitrate)1509 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsPTimeAsPacketSize)1559 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsNoCodecs)1594 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsDTMFOnTop)1602 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNOnTop)1621 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNandDTMFAsCaller)1639 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNandDTMFAsCallee)1666 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCNNoMatch)1700 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsCaseInsensitive)1736 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDAsCaller)1763 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDAsCallee)1783 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsREDNoParams)1808 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED1)1827 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED2)1846 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED3)1865 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED4)1884 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsBadRED5)1903 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SendAudioLevelHeaderExtensions)1922 TEST_F(WebRtcVoiceEngineTestFake, SendAudioLevelHeaderExtensions) {
1923   TestSetSendRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1924 }
TEST_F(WebRtcVoiceEngineTestFake,RecvAudioLevelHeaderExtensions)1925 TEST_F(WebRtcVoiceEngineTestFake, RecvAudioLevelHeaderExtensions) {
1926   TestSetRecvRtpHeaderExtensions(kRtpAudioLevelHeaderExtension);
1927 }
1928 
1929 // Test support for absolute send time header extension.
TEST_F(WebRtcVoiceEngineTestFake,SendAbsoluteSendTimeHeaderExtensions)1930 TEST_F(WebRtcVoiceEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
1931   TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1932 }
TEST_F(WebRtcVoiceEngineTestFake,RecvAbsoluteSendTimeHeaderExtensions)1933 TEST_F(WebRtcVoiceEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
1934   TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
1935 }
1936 
1937 // Test that we can create a channel and start sending on it.
TEST_F(WebRtcVoiceEngineTestFake,Send)1938 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,Playout)1949 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,CreateAndDeleteMultipleSendStreams)1960 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendCodecsWithMultipleSendStreams)1984 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendWithMultipleSendStreams)2022 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,GetStatsWithMultipleSendStreams)2051 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,PlayoutWithMultipleStreams)2109 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,CodianSend)2163 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,TxAgcConfigViaOptions)2182 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SampleRatesViaOptions)2206 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrc)2222 TEST_F(WebRtcVoiceEngineTestFake, SetSendSsrc) {
2223   EXPECT_TRUE(SetupEngineWithSendStream());
2224   EXPECT_TRUE(call_.GetAudioSendStream(kSsrc1));
2225 }
2226 
TEST_F(WebRtcVoiceEngineTestFake,GetStats)2227 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrcWithMultipleStreams)2283 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,SetSendSsrcAfterCreatingReceiveChannel)2293 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,Recv)2307 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,RecvWithMultipleStreams)2316 TEST_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).
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalled)2361 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalledWithSsrcSwitch)2371 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,RecvUnsignalledAfterSignalled)2391 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamFail)2418 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddSendStreamFail)2425 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStream)2432 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AddRecvStreamUnsupportedCodec)2441 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,StreamCleanup)2459 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,TestAddRecvStreamFailWithZeroSsrc)2470 TEST_F(WebRtcVoiceEngineTestFake, TestAddRecvStreamFailWithZeroSsrc) {
2471   EXPECT_TRUE(SetupEngineWithSendStream());
2472   EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
2473 }
2474 
TEST_F(WebRtcVoiceEngineTestFake,TestNoLeakingWhenAddRecvStreamFail)2475 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnDefaultSendStreamAsCaller)2490 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCaller) {
2491   TestInsertDtmf(0, true);
2492 }
2493 
2494 // Test the InsertDtmf on default send stream as callee
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnDefaultSendStreamAsCallee)2495 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnDefaultSendStreamAsCallee) {
2496   TestInsertDtmf(0, false);
2497 }
2498 
2499 // Test the InsertDtmf on specified send stream as caller.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnSendStreamAsCaller)2500 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCaller) {
2501   TestInsertDtmf(kSsrc1, true);
2502 }
2503 
2504 // Test the InsertDtmf on specified send stream as callee.
TEST_F(WebRtcVoiceEngineTestFake,InsertDtmfOnSendStreamAsCallee)2505 TEST_F(WebRtcVoiceEngineTestFake, InsertDtmfOnSendStreamAsCallee) {
2506   TestInsertDtmf(kSsrc1, false);
2507 }
2508 
TEST_F(WebRtcVoiceEngineTestFake,TestSetPlayoutError)2509 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetAudioOptions)2521 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,DefaultOptions)2677 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,InitDoesNotOverwriteDefaultAgcConfig)2704 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetOptionOverridesViaChannels)2720 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,TestSetDscpOptions)2821 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,TestGetReceiveChannelId)2840 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,TestGetSendChannelId)2856 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetOutputVolume)2872 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetOutputVolumeDefaultRecvStream)2885 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,SetsSyncGroupFromSyncLabel)2898 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,CanChangeCombinedBweOption)2920 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,ConfigureCombinedBweForNewRecvStreams)2965 TEST_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.)
TEST_F(WebRtcVoiceEngineTestFake,ConfiguresAudioReceiveStreamRtpExtensions)2984 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,DeliverAudioPacket_Call)3038 TEST_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.
TEST_F(WebRtcVoiceEngineTestFake,AssociateFirstSendChannel)3070 TEST_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 
TEST_F(WebRtcVoiceEngineTestFake,AssociateChannelResetUponDeleteChannnel)3086 TEST_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.
TEST(WebRtcVoiceEngineTest,StartupShutdown)3109 TEST(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.
TEST(WebRtcVoiceEngineTest,HasCorrectCodecs)3126 TEST(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
TEST(WebRtcVoiceEngineTest,Has32Channels)3211 TEST(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.
TEST(WebRtcVoiceEngineTest,SetRecvCodecs)3237 TEST(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