blob: f0e92387145eac64a9f6d808f24efafa9fea35df [file] [log] [blame]
deadbeefe814a0d2017-02-26 02:15:091/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <memory>
12
Karl Wiberg3e9e5b32017-11-06 04:01:5613#include "api/audio_codecs/builtin_audio_decoder_factory.h"
14#include "api/audio_codecs/builtin_audio_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3115#include "media/base/fakemediaengine.h"
16#include "ortc/ortcfactory.h"
17#include "ortc/testrtpparameters.h"
18#include "p2p/base/fakepackettransport.h"
19#include "pc/test/fakevideotracksource.h"
20#include "rtc_base/gunit.h"
deadbeefe814a0d2017-02-26 02:15:0921
22namespace webrtc {
23
24// This test uses an individual RtpReceiver using only the public interface,
25// and verifies that it behaves as designed at an API level. Also tests that
26// parameters are applied to the audio/video engines as expected. Network and
27// media interfaces are faked to isolate what's being tested.
28//
29// This test shouldn't result any any actual media being sent. That sort of
30// test should go in ortcfactory_integrationtest.cc.
31class OrtcRtpReceiverTest : public testing::Test {
32 public:
33 OrtcRtpReceiverTest() : fake_packet_transport_("fake") {
34 fake_media_engine_ = new cricket::FakeMediaEngine();
35 // Note: This doesn't need to use fake network classes, since we already
36 // use FakePacketTransport.
37 auto ortc_factory_result = OrtcFactory::Create(
38 nullptr, nullptr, nullptr, nullptr, nullptr,
Karl Wiberg3e9e5b32017-11-06 04:01:5639 std::unique_ptr<cricket::MediaEngineInterface>(fake_media_engine_),
40 CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory());
deadbeefe814a0d2017-02-26 02:15:0941 ortc_factory_ = ortc_factory_result.MoveValue();
sprangdb2a9fc2017-08-09 13:42:3242 RtpTransportParameters parameters;
43 parameters.rtcp.mux = true;
deadbeefe814a0d2017-02-26 02:15:0944 auto rtp_transport_result = ortc_factory_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 13:42:3245 parameters, &fake_packet_transport_, nullptr, nullptr);
deadbeefe814a0d2017-02-26 02:15:0946 rtp_transport_ = rtp_transport_result.MoveValue();
47 }
48
49 protected:
50 // Owned by |ortc_factory_|.
51 cricket::FakeMediaEngine* fake_media_engine_;
52 rtc::FakePacketTransport fake_packet_transport_;
53 std::unique_ptr<OrtcFactoryInterface> ortc_factory_;
54 std::unique_ptr<RtpTransportInterface> rtp_transport_;
55};
56
57// See ortcrtpreceiverinterface.h for the current expectations of what GetTrack
58// will return after calls to Receive.
59// TODO(deadbeef): Replace this test when the non-standard behavior is fixed
60// and GetTrack starts returning the same track for the lifetime of the
61// receiver.
62TEST_F(OrtcRtpReceiverTest, GetTrack) {
63 auto receiver_result = ortc_factory_->CreateRtpReceiver(
64 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
65 ASSERT_TRUE(receiver_result.ok());
66 auto receiver = receiver_result.MoveValue();
67
68 // Track initially expected to be null.
69 EXPECT_EQ(nullptr, receiver_result.value().get());
70
71 EXPECT_TRUE(receiver->Receive(MakeMinimalVp8ParametersWithNoSsrc()).ok());
72 auto initial_track = receiver->GetTrack();
73 EXPECT_NE(nullptr, initial_track);
74
75 // Codec changing but SSRC (or lack thereof) isn't; shouldn't create new track
76 EXPECT_TRUE(receiver->Receive(MakeMinimalVp9ParametersWithNoSsrc()).ok());
77 EXPECT_EQ(initial_track, receiver->GetTrack());
78
79 // Explicitly set SSRC and expect a different track.
80 EXPECT_TRUE(
81 receiver->Receive(MakeMinimalVp9ParametersWithSsrc(0xdeadbeef)).ok());
82 auto next_track = receiver->GetTrack();
83 EXPECT_NE(next_track, initial_track);
84
85 // Deactivating the encoding shouldn't change the track.
86 RtpParameters inactive_encoding =
87 MakeMinimalVp9ParametersWithSsrc(0xdeadbeef);
88 inactive_encoding.encodings[0].active = false;
89 EXPECT_TRUE(receiver->Receive(inactive_encoding).ok());
90 EXPECT_EQ(next_track, receiver->GetTrack());
91
92 // Removing all encodings *is* expected to clear the track.
93 RtpParameters no_encodings = MakeMinimalVp9ParametersWithSsrc(0xdeadbeef);
94 no_encodings.encodings.clear();
95 EXPECT_TRUE(receiver->Receive(no_encodings).ok());
96 EXPECT_EQ(nullptr, receiver->GetTrack());
97}
98
99// Currently SetTransport isn't supported. When it is, replace this test with a
100// test/tests for it.
101TEST_F(OrtcRtpReceiverTest, SetTransportFails) {
102 rtc::FakePacketTransport fake_packet_transport("another_transport");
sprangdb2a9fc2017-08-09 13:42:32103 RtpTransportParameters parameters;
104 parameters.rtcp.mux = true;
deadbeefe814a0d2017-02-26 02:15:09105 auto rtp_transport_result = ortc_factory_->CreateRtpTransport(
sprangdb2a9fc2017-08-09 13:42:32106 parameters, &fake_packet_transport, nullptr, nullptr);
deadbeefe814a0d2017-02-26 02:15:09107 auto rtp_transport = rtp_transport_result.MoveValue();
108
109 auto receiver_result = ortc_factory_->CreateRtpReceiver(
110 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
111 auto receiver = receiver_result.MoveValue();
112 EXPECT_EQ(RTCErrorType::UNSUPPORTED_OPERATION,
113 receiver->SetTransport(rtp_transport.get()).type());
114}
115
116TEST_F(OrtcRtpReceiverTest, GetTransport) {
117 auto result = ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO,
118 rtp_transport_.get());
119 EXPECT_EQ(rtp_transport_.get(), result.value()->GetTransport());
120}
121
122// Test that "Receive" causes the expected parameters to be applied to the media
123// engine level, for an audio receiver.
124TEST_F(OrtcRtpReceiverTest, ReceiveAppliesAudioParametersToMediaEngine) {
125 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
126 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
127 auto audio_receiver = audio_receiver_result.MoveValue();
128
129 // First, create parameters with all the bells and whistles.
130 RtpParameters parameters;
131
132 RtpCodecParameters opus_codec;
133 opus_codec.name = "opus";
134 opus_codec.kind = cricket::MEDIA_TYPE_AUDIO;
135 opus_codec.payload_type = 120;
136 opus_codec.clock_rate.emplace(48000);
137 opus_codec.num_channels.emplace(2);
138 opus_codec.parameters["minptime"] = "10";
139 opus_codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
140 parameters.codecs.push_back(std::move(opus_codec));
141
142 // Add two codecs, expecting the first to be used.
143 // TODO(deadbeef): Once "codec_payload_type" is supported, use it to select a
144 // codec that's not at the top of the list.
145 RtpCodecParameters isac_codec;
146 isac_codec.name = "ISAC";
147 isac_codec.kind = cricket::MEDIA_TYPE_AUDIO;
148 isac_codec.payload_type = 110;
149 isac_codec.clock_rate.emplace(16000);
150 parameters.codecs.push_back(std::move(isac_codec));
151
152 RtpEncodingParameters encoding;
153 encoding.ssrc.emplace(0xdeadbeef);
154 parameters.encodings.push_back(std::move(encoding));
155
156 parameters.header_extensions.emplace_back(
157 "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 3);
158
159 EXPECT_TRUE(audio_receiver->Receive(parameters).ok());
160
161 // Now verify that the parameters were applied to the fake media engine layer
162 // that exists below BaseChannel.
163 cricket::FakeVoiceMediaChannel* fake_voice_channel =
164 fake_media_engine_->GetVoiceChannel(0);
165 ASSERT_NE(nullptr, fake_voice_channel);
166 EXPECT_TRUE(fake_voice_channel->playout());
167
168 // Verify codec parameters.
169 ASSERT_GT(fake_voice_channel->recv_codecs().size(), 0u);
170 const cricket::AudioCodec& top_codec = fake_voice_channel->recv_codecs()[0];
171 EXPECT_EQ("opus", top_codec.name);
172 EXPECT_EQ(120, top_codec.id);
173 EXPECT_EQ(48000, top_codec.clockrate);
174 EXPECT_EQ(2u, top_codec.channels);
175 ASSERT_NE(top_codec.params.end(), top_codec.params.find("minptime"));
176 EXPECT_EQ("10", top_codec.params.at("minptime"));
177
178 // Verify encoding parameters.
179 ASSERT_EQ(1u, fake_voice_channel->recv_streams().size());
180 const cricket::StreamParams& recv_stream =
181 fake_voice_channel->recv_streams()[0];
182 EXPECT_EQ(1u, recv_stream.ssrcs.size());
183 EXPECT_EQ(0xdeadbeef, recv_stream.first_ssrc());
184
185 // Verify header extensions.
186 ASSERT_EQ(1u, fake_voice_channel->recv_extensions().size());
187 const RtpExtension& extension = fake_voice_channel->recv_extensions()[0];
188 EXPECT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level", extension.uri);
189 EXPECT_EQ(3, extension.id);
190}
191
192// Test that "Receive" causes the expected parameters to be applied to the media
193// engine level, for a video receiver.
194TEST_F(OrtcRtpReceiverTest, ReceiveAppliesVideoParametersToMediaEngine) {
195 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
196 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
197 auto video_receiver = video_receiver_result.MoveValue();
198
199 // First, create parameters with all the bells and whistles.
200 RtpParameters parameters;
201
202 RtpCodecParameters vp8_codec;
203 vp8_codec.name = "VP8";
204 vp8_codec.kind = cricket::MEDIA_TYPE_VIDEO;
205 vp8_codec.payload_type = 99;
206 // Try a couple types of feedback params. "Generic NACK" is a bit of a
207 // special case, so test it here.
208 vp8_codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
209 RtcpFeedbackMessageType::FIR);
210 vp8_codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
211 RtcpFeedbackMessageType::GENERIC_NACK);
212 parameters.codecs.push_back(std::move(vp8_codec));
213
214 RtpCodecParameters vp8_rtx_codec;
215 vp8_rtx_codec.name = "rtx";
216 vp8_rtx_codec.kind = cricket::MEDIA_TYPE_VIDEO;
217 vp8_rtx_codec.payload_type = 100;
218 vp8_rtx_codec.parameters["apt"] = "99";
219 parameters.codecs.push_back(std::move(vp8_rtx_codec));
220
221 // Add two codecs, expecting the first to be used.
222 // TODO(deadbeef): Once "codec_payload_type" is supported, use it to select a
223 // codec that's not at the top of the list.
224 RtpCodecParameters vp9_codec;
225 vp9_codec.name = "VP9";
226 vp9_codec.kind = cricket::MEDIA_TYPE_VIDEO;
227 vp9_codec.payload_type = 102;
228 parameters.codecs.push_back(std::move(vp9_codec));
229
230 RtpCodecParameters vp9_rtx_codec;
231 vp9_rtx_codec.name = "rtx";
232 vp9_rtx_codec.kind = cricket::MEDIA_TYPE_VIDEO;
233 vp9_rtx_codec.payload_type = 103;
234 vp9_rtx_codec.parameters["apt"] = "102";
235 parameters.codecs.push_back(std::move(vp9_rtx_codec));
236
237 RtpEncodingParameters encoding;
238 encoding.ssrc.emplace(0xdeadbeef);
239 encoding.rtx.emplace(0xbaadfeed);
240 parameters.encodings.push_back(std::move(encoding));
241
242 parameters.header_extensions.emplace_back("urn:3gpp:video-orientation", 4);
243 parameters.header_extensions.emplace_back(
244 "http://www.webrtc.org/experiments/rtp-hdrext/playout-delay", 6);
245
246 EXPECT_TRUE(video_receiver->Receive(parameters).ok());
247
248 // Now verify that the parameters were applied to the fake media engine layer
249 // that exists below BaseChannel.
250 cricket::FakeVideoMediaChannel* fake_video_channel =
251 fake_media_engine_->GetVideoChannel(0);
252 ASSERT_NE(nullptr, fake_video_channel);
253
254 // Verify codec parameters.
255 ASSERT_GE(fake_video_channel->recv_codecs().size(), 2u);
256 const cricket::VideoCodec& top_codec = fake_video_channel->recv_codecs()[0];
257 EXPECT_EQ("VP8", top_codec.name);
258 EXPECT_EQ(99, top_codec.id);
259 EXPECT_TRUE(top_codec.feedback_params.Has({"ccm", "fir"}));
260 EXPECT_TRUE(top_codec.feedback_params.Has(cricket::FeedbackParam("nack")));
261
262 const cricket::VideoCodec& rtx_codec = fake_video_channel->recv_codecs()[1];
263 EXPECT_EQ("rtx", rtx_codec.name);
264 EXPECT_EQ(100, rtx_codec.id);
265 ASSERT_NE(rtx_codec.params.end(), rtx_codec.params.find("apt"));
266 EXPECT_EQ("99", rtx_codec.params.at("apt"));
267
268 // Verify encoding parameters.
269 ASSERT_EQ(1u, fake_video_channel->recv_streams().size());
270 const cricket::StreamParams& recv_stream =
271 fake_video_channel->recv_streams()[0];
272 EXPECT_EQ(2u, recv_stream.ssrcs.size());
273 EXPECT_EQ(0xdeadbeef, recv_stream.first_ssrc());
274 uint32_t rtx_ssrc = 0u;
275 EXPECT_TRUE(recv_stream.GetFidSsrc(recv_stream.first_ssrc(), &rtx_ssrc));
276 EXPECT_EQ(0xbaadfeed, rtx_ssrc);
277
278 // Verify header extensions.
279 ASSERT_EQ(2u, fake_video_channel->recv_extensions().size());
280 const RtpExtension& extension1 = fake_video_channel->recv_extensions()[0];
281 EXPECT_EQ("urn:3gpp:video-orientation", extension1.uri);
282 EXPECT_EQ(4, extension1.id);
283 const RtpExtension& extension2 = fake_video_channel->recv_extensions()[1];
284 EXPECT_EQ("http://www.webrtc.org/experiments/rtp-hdrext/playout-delay",
285 extension2.uri);
286 EXPECT_EQ(6, extension2.id);
287}
288
289// Test changing both the receive codec and SSRC at the same time, and verify
290// that the new parameters are applied to the media engine level.
291TEST_F(OrtcRtpReceiverTest, CallingReceiveTwiceChangesParameters) {
292 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
293 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
294 auto audio_receiver = audio_receiver_result.MoveValue();
295 RTCError error =
296 audio_receiver->Receive(MakeMinimalOpusParametersWithSsrc(0x11111111));
297 EXPECT_TRUE(error.ok());
298 error =
299 audio_receiver->Receive(MakeMinimalIsacParametersWithSsrc(0x22222222));
300 EXPECT_TRUE(error.ok());
301
302 cricket::FakeVoiceMediaChannel* fake_voice_channel =
303 fake_media_engine_->GetVoiceChannel(0);
304 ASSERT_NE(nullptr, fake_voice_channel);
305 ASSERT_GT(fake_voice_channel->recv_codecs().size(), 0u);
306 EXPECT_EQ("ISAC", fake_voice_channel->recv_codecs()[0].name);
307 ASSERT_EQ(1u, fake_voice_channel->recv_streams().size());
308 EXPECT_EQ(0x22222222u, fake_voice_channel->recv_streams()[0].first_ssrc());
309
310 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
311 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
312 auto video_receiver = video_receiver_result.MoveValue();
313 error = video_receiver->Receive(MakeMinimalVp8ParametersWithSsrc(0x33333333));
314 EXPECT_TRUE(error.ok());
315 error = video_receiver->Receive(MakeMinimalVp9ParametersWithSsrc(0x44444444));
316 EXPECT_TRUE(error.ok());
317
318 cricket::FakeVideoMediaChannel* fake_video_channel =
319 fake_media_engine_->GetVideoChannel(0);
320 ASSERT_NE(nullptr, fake_video_channel);
321 ASSERT_GT(fake_video_channel->recv_codecs().size(), 0u);
322 EXPECT_EQ("VP9", fake_video_channel->recv_codecs()[0].name);
323 ASSERT_EQ(1u, fake_video_channel->recv_streams().size());
324 EXPECT_EQ(0x44444444u, fake_video_channel->recv_streams()[0].first_ssrc());
325}
326
327// Ensure that if the |active| flag of RtpEncodingParameters is set to false,
328// playout stops at the media engine level. Note that this is only applicable
329// to audio (at least currently).
330TEST_F(OrtcRtpReceiverTest, DeactivatingEncodingStopsPlayout) {
331 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
332 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
333 auto audio_receiver = audio_receiver_result.MoveValue();
334 RtpParameters parameters = MakeMinimalOpusParameters();
335 EXPECT_TRUE(audio_receiver->Receive(parameters).ok());
336
337 // Expect "playout" flag to initially be true.
338 cricket::FakeVoiceMediaChannel* fake_voice_channel =
339 fake_media_engine_->GetVoiceChannel(0);
340 ASSERT_NE(nullptr, fake_voice_channel);
341 EXPECT_TRUE(fake_voice_channel->playout());
342
343 // Deactivate encoding and expect it to change to false.
344 parameters.encodings[0].active = false;
345 EXPECT_TRUE(audio_receiver->Receive(parameters).ok());
346 EXPECT_FALSE(fake_voice_channel->playout());
347}
348
349// Ensure that calling Receive with an empty list of encodings causes receive
350// streams at the media engine level to be cleared.
351TEST_F(OrtcRtpReceiverTest,
352 CallingReceiveWithEmptyEncodingsClearsReceiveStreams) {
353 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
354 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
355 auto audio_receiver = audio_receiver_result.MoveValue();
356 RtpParameters parameters = MakeMinimalOpusParameters();
357 EXPECT_TRUE(audio_receiver->Receive(parameters).ok());
358 parameters.encodings.clear();
359 EXPECT_TRUE(audio_receiver->Receive(parameters).ok());
360
361 cricket::FakeVoiceMediaChannel* fake_voice_channel =
362 fake_media_engine_->GetVoiceChannel(0);
363 ASSERT_NE(nullptr, fake_voice_channel);
364 EXPECT_TRUE(fake_voice_channel->recv_streams().empty());
365
366 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
367 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
368 auto video_receiver = video_receiver_result.MoveValue();
369 parameters = MakeMinimalVp8Parameters();
370 EXPECT_TRUE(video_receiver->Receive(parameters).ok());
371 parameters.encodings.clear();
372 EXPECT_TRUE(video_receiver->Receive(parameters).ok());
373
374 cricket::FakeVideoMediaChannel* fake_video_channel =
375 fake_media_engine_->GetVideoChannel(0);
376 ASSERT_NE(nullptr, fake_video_channel);
377 EXPECT_TRUE(fake_video_channel->recv_streams().empty());
378}
379
380// These errors should be covered by rtpparametersconversion_unittest.cc, but
381// we should at least test that those errors are propogated from calls to
382// Receive, with a few examples.
383TEST_F(OrtcRtpReceiverTest, ReceiveReturnsErrorOnInvalidParameters) {
384 auto result = ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO,
385 rtp_transport_.get());
386 auto receiver = result.MoveValue();
387 // CCM feedback missing message type.
388 RtpParameters invalid_feedback = MakeMinimalOpusParameters();
389 invalid_feedback.codecs[0].rtcp_feedback.emplace_back(RtcpFeedbackType::CCM);
390 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER,
391 receiver->Receive(invalid_feedback).type());
392 // Payload type greater than 127.
393 RtpParameters invalid_pt = MakeMinimalOpusParameters();
394 invalid_pt.codecs[0].payload_type = 128;
395 EXPECT_EQ(RTCErrorType::INVALID_RANGE, receiver->Receive(invalid_pt).type());
396 // Duplicate header extension IDs.
397 RtpParameters duplicate_ids = MakeMinimalOpusParameters();
398 duplicate_ids.header_extensions.emplace_back("foo", 5);
399 duplicate_ids.header_extensions.emplace_back("bar", 5);
400 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER,
401 receiver->Receive(duplicate_ids).type());
402}
403
404// Two receivers using the same transport shouldn't be able to use the same
405// payload type to refer to different codecs, same header extension IDs to
406// refer to different extensions, or same SSRC.
407TEST_F(OrtcRtpReceiverTest, ReceiveReturnsErrorOnIdConflicts) {
408 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
409 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
410 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
411 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
412 auto audio_receiver = audio_receiver_result.MoveValue();
413 auto video_receiver = video_receiver_result.MoveValue();
414
415 // First test payload type conflict.
416 RtpParameters audio_parameters = MakeMinimalOpusParameters();
417 RtpParameters video_parameters = MakeMinimalVp8Parameters();
418 audio_parameters.codecs[0].payload_type = 100;
419 video_parameters.codecs[0].payload_type = 100;
420 EXPECT_TRUE(audio_receiver->Receive(audio_parameters).ok());
421 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER,
422 video_receiver->Receive(video_parameters).type());
423
424 // Test header extension ID conflict.
425 video_parameters.codecs[0].payload_type = 110;
426 audio_parameters.header_extensions.emplace_back("foo", 4);
427 video_parameters.header_extensions.emplace_back("bar", 4);
428 EXPECT_TRUE(audio_receiver->Receive(audio_parameters).ok());
429 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER,
430 video_receiver->Receive(video_parameters).type());
431
432 // Test SSRC conflict. Have an RTX SSRC that conflicts with a primary SSRC
433 // for extra challenge.
434 video_parameters.header_extensions[0].uri = "foo";
435 audio_parameters.encodings[0].ssrc.emplace(0xabbaabba);
436 audio_parameters.encodings[0].rtx.emplace(0xdeadbeef);
437 video_parameters.encodings[0].ssrc.emplace(0xdeadbeef);
438 EXPECT_TRUE(audio_receiver->Receive(audio_parameters).ok());
439 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER,
440 video_receiver->Receive(video_parameters).type());
441
442 // Sanity check that parameters can be set if the conflicts are all resolved.
443 video_parameters.encodings[0].ssrc.emplace(0xbaadf00d);
444 EXPECT_TRUE(video_receiver->Receive(video_parameters).ok());
445}
446
447// Ensure that deleting a receiver causes receive streams at the media engine
448// level to be cleared.
449TEST_F(OrtcRtpReceiverTest, DeletingReceiverClearsReceiveStreams) {
450 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
451 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
452 auto audio_receiver = audio_receiver_result.MoveValue();
453 EXPECT_TRUE(audio_receiver->Receive(MakeMinimalOpusParameters()).ok());
454
455 // Also create an audio sender, to prevent the voice channel from being
456 // completely deleted.
457 auto audio_sender_result = ortc_factory_->CreateRtpSender(
458 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
459 auto audio_sender = audio_sender_result.MoveValue();
460 EXPECT_TRUE(audio_sender->Send(MakeMinimalOpusParameters()).ok());
461
462 audio_receiver.reset(nullptr);
463 cricket::FakeVoiceMediaChannel* fake_voice_channel =
464 fake_media_engine_->GetVoiceChannel(0);
465 ASSERT_NE(nullptr, fake_voice_channel);
466 EXPECT_TRUE(fake_voice_channel->recv_streams().empty());
467
468 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
469 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
470 auto video_receiver = video_receiver_result.MoveValue();
471 EXPECT_TRUE(video_receiver->Receive(MakeMinimalVp8Parameters()).ok());
472
473 // Also create an video sender, to prevent the video channel from being
474 // completely deleted.
475 auto video_sender_result = ortc_factory_->CreateRtpSender(
476 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
477 auto video_sender = video_sender_result.MoveValue();
478 EXPECT_TRUE(video_sender->Send(MakeMinimalVp8Parameters()).ok());
479
480 video_receiver.reset(nullptr);
481 cricket::FakeVideoMediaChannel* fake_video_channel =
482 fake_media_engine_->GetVideoChannel(0);
483 ASSERT_NE(nullptr, fake_video_channel);
484 EXPECT_TRUE(fake_video_channel->recv_streams().empty());
485}
486
487// If Receive hasn't been called, GetParameters should return empty parameters.
488TEST_F(OrtcRtpReceiverTest, GetDefaultParameters) {
489 auto result = ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_AUDIO,
490 rtp_transport_.get());
491 EXPECT_EQ(RtpParameters(), result.value()->GetParameters());
492 result = ortc_factory_->CreateRtpReceiver(cricket::MEDIA_TYPE_VIDEO,
493 rtp_transport_.get());
494 EXPECT_EQ(RtpParameters(), result.value()->GetParameters());
495}
496
497// Test that GetParameters returns the last parameters passed into Receive,
498// along with the implementation-default values filled in where they were left
499// unset.
500TEST_F(OrtcRtpReceiverTest,
501 GetParametersReturnsLastSetParametersWithDefaultsFilled) {
502 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
503 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
504 auto audio_receiver = audio_receiver_result.MoveValue();
505
506 RtpParameters opus_parameters = MakeMinimalOpusParameters();
507 EXPECT_TRUE(audio_receiver->Receive(opus_parameters).ok());
508 EXPECT_EQ(opus_parameters, audio_receiver->GetParameters());
509
510 RtpParameters isac_parameters = MakeMinimalIsacParameters();
511 // Sanity check that num_channels actually is left unset.
512 ASSERT_FALSE(isac_parameters.codecs[0].num_channels);
513 EXPECT_TRUE(audio_receiver->Receive(isac_parameters).ok());
514 // Should be filled with a default "num channels" of 1.
515 // TODO(deadbeef): This should actually default to 2 for some codecs. Update
516 // this test once that's implemented.
517 isac_parameters.codecs[0].num_channels.emplace(1);
518 EXPECT_EQ(isac_parameters, audio_receiver->GetParameters());
519
520 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
521 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
522 auto video_receiver = video_receiver_result.MoveValue();
523
524 RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
525 // Sanity check that clock_rate actually is left unset.
526 EXPECT_TRUE(video_receiver->Receive(vp8_parameters).ok());
527 // Should be filled with a default clock rate of 90000.
528 vp8_parameters.codecs[0].clock_rate.emplace(90000);
529 EXPECT_EQ(vp8_parameters, video_receiver->GetParameters());
530
531 RtpParameters vp9_parameters = MakeMinimalVp9Parameters();
532 // Sanity check that clock_rate actually is left unset.
533 EXPECT_TRUE(video_receiver->Receive(vp9_parameters).ok());
534 // Should be filled with a default clock rate of 90000.
535 vp9_parameters.codecs[0].clock_rate.emplace(90000);
536 EXPECT_EQ(vp9_parameters, video_receiver->GetParameters());
537}
538
539TEST_F(OrtcRtpReceiverTest, GetKind) {
540 auto audio_receiver_result = ortc_factory_->CreateRtpReceiver(
541 cricket::MEDIA_TYPE_AUDIO, rtp_transport_.get());
542 auto video_receiver_result = ortc_factory_->CreateRtpReceiver(
543 cricket::MEDIA_TYPE_VIDEO, rtp_transport_.get());
544 auto audio_receiver = audio_receiver_result.MoveValue();
545 auto video_receiver = video_receiver_result.MoveValue();
546 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, audio_receiver->GetKind());
547 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, video_receiver->GetKind());
548}
549
550} // namespace webrtc