xref: /aosp_15_r20/external/webrtc/pc/rtp_transceiver_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2018 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 // This file contains tests for `RtpTransceiver`.
12 
13 #include "pc/rtp_transceiver.h"
14 
15 #include <memory>
16 #include <utility>
17 
18 #include "absl/strings/string_view.h"
19 #include "absl/types/optional.h"
20 #include "api/peer_connection_interface.h"
21 #include "api/rtp_parameters.h"
22 #include "media/base/fake_media_engine.h"
23 #include "media/base/media_engine.h"
24 #include "pc/test/mock_channel_interface.h"
25 #include "pc/test/mock_rtp_receiver_internal.h"
26 #include "pc/test/mock_rtp_sender_internal.h"
27 #include "rtc_base/thread.h"
28 #include "test/gmock.h"
29 #include "test/gtest.h"
30 
31 using ::testing::_;
32 using ::testing::ElementsAre;
33 using ::testing::Optional;
34 using ::testing::Property;
35 using ::testing::Return;
36 using ::testing::ReturnRef;
37 
38 namespace webrtc {
39 
40 namespace {
41 
42 class RtpTransceiverTest : public testing::Test {
43  public:
RtpTransceiverTest()44   RtpTransceiverTest()
45       : dependencies_(MakeDependencies()),
46         context_(ConnectionContext::Create(&dependencies_)) {}
47 
48  protected:
media_engine()49   cricket::MediaEngineInterface* media_engine() {
50     return context_->media_engine();
51   }
context()52   ConnectionContext* context() { return context_.get(); }
53 
54  private:
55   rtc::AutoThread main_thread_;
56 
MakeDependencies()57   static PeerConnectionFactoryDependencies MakeDependencies() {
58     PeerConnectionFactoryDependencies d;
59     d.network_thread = rtc::Thread::Current();
60     d.worker_thread = rtc::Thread::Current();
61     d.signaling_thread = rtc::Thread::Current();
62     d.media_engine = std::make_unique<cricket::FakeMediaEngine>();
63     return d;
64   }
65 
66   PeerConnectionFactoryDependencies dependencies_;
67   rtc::scoped_refptr<ConnectionContext> context_;
68 };
69 
70 // Checks that a channel cannot be set on a stopped `RtpTransceiver`.
TEST_F(RtpTransceiverTest,CannotSetChannelOnStoppedTransceiver)71 TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
72   const std::string content_name("my_mid");
73   auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
74       cricket::MediaType::MEDIA_TYPE_AUDIO, context());
75   auto channel1 = std::make_unique<cricket::MockChannelInterface>();
76   EXPECT_CALL(*channel1, media_type())
77       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
78   EXPECT_CALL(*channel1, mid()).WillRepeatedly(ReturnRef(content_name));
79   EXPECT_CALL(*channel1, SetFirstPacketReceivedCallback(_));
80   EXPECT_CALL(*channel1, SetRtpTransport(_)).WillRepeatedly(Return(true));
81   auto channel1_ptr = channel1.get();
82   transceiver->SetChannel(std::move(channel1), [&](const std::string& mid) {
83     EXPECT_EQ(mid, content_name);
84     return nullptr;
85   });
86   EXPECT_EQ(channel1_ptr, transceiver->channel());
87 
88   // Stop the transceiver.
89   transceiver->StopInternal();
90   EXPECT_EQ(channel1_ptr, transceiver->channel());
91 
92   auto channel2 = std::make_unique<cricket::MockChannelInterface>();
93   EXPECT_CALL(*channel2, media_type())
94       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
95 
96   // Clear the current channel - required to allow SetChannel()
97   EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
98   transceiver->ClearChannel();
99   // Channel can no longer be set, so this call should be a no-op.
100   transceiver->SetChannel(std::move(channel2),
101                           [](const std::string&) { return nullptr; });
102   EXPECT_EQ(nullptr, transceiver->channel());
103 }
104 
105 // Checks that a channel can be unset on a stopped `RtpTransceiver`
TEST_F(RtpTransceiverTest,CanUnsetChannelOnStoppedTransceiver)106 TEST_F(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
107   const std::string content_name("my_mid");
108   auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
109       cricket::MediaType::MEDIA_TYPE_VIDEO, context());
110   auto channel = std::make_unique<cricket::MockChannelInterface>();
111   EXPECT_CALL(*channel, media_type())
112       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
113   EXPECT_CALL(*channel, mid()).WillRepeatedly(ReturnRef(content_name));
114   EXPECT_CALL(*channel, SetFirstPacketReceivedCallback(_))
115       .WillRepeatedly(testing::Return());
116   EXPECT_CALL(*channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
117 
118   auto channel_ptr = channel.get();
119   transceiver->SetChannel(std::move(channel), [&](const std::string& mid) {
120     EXPECT_EQ(mid, content_name);
121     return nullptr;
122   });
123   EXPECT_EQ(channel_ptr, transceiver->channel());
124 
125   // Stop the transceiver.
126   transceiver->StopInternal();
127   EXPECT_EQ(channel_ptr, transceiver->channel());
128 
129   // Set the channel to `nullptr`.
130   transceiver->ClearChannel();
131   EXPECT_EQ(nullptr, transceiver->channel());
132 }
133 
134 class RtpTransceiverUnifiedPlanTest : public RtpTransceiverTest {
135  public:
RtpTransceiverUnifiedPlanTest()136   RtpTransceiverUnifiedPlanTest()
137       : transceiver_(rtc::make_ref_counted<RtpTransceiver>(
138             RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
139                 rtc::Thread::Current(),
140                 sender_),
141             RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
142                 rtc::Thread::Current(),
143                 rtc::Thread::Current(),
144                 receiver_),
145             context(),
146             media_engine()->voice().GetRtpHeaderExtensions(),
147             /* on_negotiation_needed= */ [] {})) {}
148 
MockReceiver()149   static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
150     auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
151     EXPECT_CALL(*receiver.get(), media_type())
152         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
153     return receiver;
154   }
155 
MockSender()156   static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
157     auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
158     EXPECT_CALL(*sender.get(), media_type())
159         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
160     return sender;
161   }
162 
163   rtc::AutoThread main_thread_;
164   rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
165   rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
166   rtc::scoped_refptr<RtpTransceiver> transceiver_;
167 };
168 
169 // Basic tests for Stop()
TEST_F(RtpTransceiverUnifiedPlanTest,StopSetsDirection)170 TEST_F(RtpTransceiverUnifiedPlanTest, StopSetsDirection) {
171   EXPECT_CALL(*receiver_.get(), Stop());
172   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
173   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
174   EXPECT_CALL(*sender_.get(), Stop());
175 
176   EXPECT_EQ(RtpTransceiverDirection::kInactive, transceiver_->direction());
177   EXPECT_FALSE(transceiver_->current_direction());
178   transceiver_->StopStandard();
179   EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
180   EXPECT_FALSE(transceiver_->current_direction());
181   transceiver_->StopTransceiverProcedure();
182   EXPECT_TRUE(transceiver_->current_direction());
183   EXPECT_EQ(RtpTransceiverDirection::kStopped, transceiver_->direction());
184   EXPECT_EQ(RtpTransceiverDirection::kStopped,
185             *transceiver_->current_direction());
186 }
187 
188 class RtpTransceiverTestForHeaderExtensions : public RtpTransceiverTest {
189  public:
RtpTransceiverTestForHeaderExtensions()190   RtpTransceiverTestForHeaderExtensions()
191       : extensions_(
192             {RtpHeaderExtensionCapability("uri1",
193                                           1,
194                                           RtpTransceiverDirection::kSendOnly),
195              RtpHeaderExtensionCapability("uri2",
196                                           2,
197                                           RtpTransceiverDirection::kRecvOnly),
198              RtpHeaderExtensionCapability(RtpExtension::kMidUri,
199                                           3,
200                                           RtpTransceiverDirection::kSendRecv),
201              RtpHeaderExtensionCapability(RtpExtension::kVideoRotationUri,
202                                           4,
203                                           RtpTransceiverDirection::kSendRecv)}),
204         transceiver_(rtc::make_ref_counted<RtpTransceiver>(
205             RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
206                 rtc::Thread::Current(),
207                 sender_),
208             RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
209                 rtc::Thread::Current(),
210                 rtc::Thread::Current(),
211                 receiver_),
212             context(),
213             extensions_,
__anon9397170d0602null214             /* on_negotiation_needed= */ [] {})) {}
215 
MockReceiver()216   static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
217     auto receiver = rtc::make_ref_counted<MockRtpReceiverInternal>();
218     EXPECT_CALL(*receiver.get(), media_type())
219         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
220     return receiver;
221   }
222 
MockSender()223   static rtc::scoped_refptr<MockRtpSenderInternal> MockSender() {
224     auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
225     EXPECT_CALL(*sender.get(), media_type())
226         .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
227     return sender;
228   }
229 
ClearChannel()230   void ClearChannel() {
231     EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
232     transceiver_->ClearChannel();
233   }
234 
235   rtc::AutoThread main_thread_;
236   rtc::scoped_refptr<MockRtpReceiverInternal> receiver_ = MockReceiver();
237   rtc::scoped_refptr<MockRtpSenderInternal> sender_ = MockSender();
238 
239   std::vector<RtpHeaderExtensionCapability> extensions_;
240   rtc::scoped_refptr<RtpTransceiver> transceiver_;
241 };
242 
TEST_F(RtpTransceiverTestForHeaderExtensions,OffersChannelManagerList)243 TEST_F(RtpTransceiverTestForHeaderExtensions, OffersChannelManagerList) {
244   EXPECT_CALL(*receiver_.get(), Stop());
245   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
246   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
247   EXPECT_CALL(*sender_.get(), Stop());
248 
249   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
250 }
251 
TEST_F(RtpTransceiverTestForHeaderExtensions,ModifiesDirection)252 TEST_F(RtpTransceiverTestForHeaderExtensions, ModifiesDirection) {
253   EXPECT_CALL(*receiver_.get(), Stop());
254   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
255   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
256   EXPECT_CALL(*sender_.get(), Stop());
257 
258   auto modified_extensions = extensions_;
259   modified_extensions[0].direction = RtpTransceiverDirection::kSendOnly;
260   EXPECT_TRUE(
261       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
262   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
263   modified_extensions[0].direction = RtpTransceiverDirection::kRecvOnly;
264   EXPECT_TRUE(
265       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
266   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
267   modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
268   EXPECT_TRUE(
269       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
270   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
271   modified_extensions[0].direction = RtpTransceiverDirection::kInactive;
272   EXPECT_TRUE(
273       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
274   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
275 }
276 
TEST_F(RtpTransceiverTestForHeaderExtensions,AcceptsStoppedExtension)277 TEST_F(RtpTransceiverTestForHeaderExtensions, AcceptsStoppedExtension) {
278   EXPECT_CALL(*receiver_.get(), Stop());
279   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
280   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
281   EXPECT_CALL(*sender_.get(), Stop());
282 
283   auto modified_extensions = extensions_;
284   modified_extensions[0].direction = RtpTransceiverDirection::kStopped;
285   EXPECT_TRUE(
286       transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions).ok());
287   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), modified_extensions);
288 }
289 
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsUnsupportedExtension)290 TEST_F(RtpTransceiverTestForHeaderExtensions, RejectsUnsupportedExtension) {
291   EXPECT_CALL(*receiver_.get(), Stop());
292   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
293   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
294   EXPECT_CALL(*sender_.get(), Stop());
295 
296   std::vector<RtpHeaderExtensionCapability> modified_extensions(
297       {RtpHeaderExtensionCapability("uri3", 1,
298                                     RtpTransceiverDirection::kSendRecv)});
299   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
300               Property(&RTCError::type, RTCErrorType::UNSUPPORTED_PARAMETER));
301   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
302 }
303 
TEST_F(RtpTransceiverTestForHeaderExtensions,RejectsStoppedMandatoryExtensions)304 TEST_F(RtpTransceiverTestForHeaderExtensions,
305        RejectsStoppedMandatoryExtensions) {
306   EXPECT_CALL(*receiver_.get(), Stop());
307   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
308   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
309   EXPECT_CALL(*sender_.get(), Stop());
310 
311   std::vector<RtpHeaderExtensionCapability> modified_extensions = extensions_;
312   // Attempting to stop the mandatory MID extension.
313   modified_extensions[2].direction = RtpTransceiverDirection::kStopped;
314   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
315               Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
316   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
317   modified_extensions = extensions_;
318   // Attempting to stop the mandatory video orientation extension.
319   modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
320   EXPECT_THAT(transceiver_->SetOfferedRtpHeaderExtensions(modified_extensions),
321               Property(&RTCError::type, RTCErrorType::INVALID_MODIFICATION));
322   EXPECT_EQ(transceiver_->HeaderExtensionsToOffer(), extensions_);
323 }
324 
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithoutChannel)325 TEST_F(RtpTransceiverTestForHeaderExtensions,
326        NoNegotiatedHdrExtsWithoutChannel) {
327   EXPECT_CALL(*receiver_.get(), Stop());
328   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
329   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
330   EXPECT_CALL(*sender_.get(), Stop());
331   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
332 }
333 
TEST_F(RtpTransceiverTestForHeaderExtensions,NoNegotiatedHdrExtsWithChannelWithoutNegotiation)334 TEST_F(RtpTransceiverTestForHeaderExtensions,
335        NoNegotiatedHdrExtsWithChannelWithoutNegotiation) {
336   const std::string content_name("my_mid");
337   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
338   EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
339   EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
340   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
341   EXPECT_CALL(*sender_.get(), Stop());
342   auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
343   auto mock_channel_ptr = mock_channel.get();
344   EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
345   EXPECT_CALL(*mock_channel, media_type())
346       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
347   EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
348   EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
349   EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
350   transceiver_->SetChannel(std::move(mock_channel),
351                            [](const std::string&) { return nullptr; });
352   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(), ElementsAre());
353 
354   EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
355   ClearChannel();
356 }
357 
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExts)358 TEST_F(RtpTransceiverTestForHeaderExtensions, ReturnsNegotiatedHdrExts) {
359   const std::string content_name("my_mid");
360   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_)).WillRepeatedly(Return());
361   EXPECT_CALL(*receiver_.get(), Stop()).WillRepeatedly(Return());
362   EXPECT_CALL(*sender_.get(), SetMediaChannel(_));
363   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
364   EXPECT_CALL(*sender_.get(), Stop());
365 
366   auto mock_channel = std::make_unique<cricket::MockChannelInterface>();
367   auto mock_channel_ptr = mock_channel.get();
368   EXPECT_CALL(*mock_channel, SetFirstPacketReceivedCallback(_));
369   EXPECT_CALL(*mock_channel, media_type())
370       .WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
371   EXPECT_CALL(*mock_channel, media_channel()).WillRepeatedly(Return(nullptr));
372   EXPECT_CALL(*mock_channel, mid()).WillRepeatedly(ReturnRef(content_name));
373   EXPECT_CALL(*mock_channel, SetRtpTransport(_)).WillRepeatedly(Return(true));
374 
375   cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
376                                              webrtc::RtpExtension("uri2", 2)};
377   cricket::AudioContentDescription description;
378   description.set_rtp_header_extensions(extensions);
379   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
380 
381   transceiver_->SetChannel(std::move(mock_channel),
382                            [](const std::string&) { return nullptr; });
383   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
384               ElementsAre(RtpHeaderExtensionCapability(
385                               "uri1", 1, RtpTransceiverDirection::kSendRecv),
386                           RtpHeaderExtensionCapability(
387                               "uri2", 2, RtpTransceiverDirection::kSendRecv)));
388 
389   EXPECT_CALL(*mock_channel_ptr, SetFirstPacketReceivedCallback(_));
390   ClearChannel();
391 }
392 
TEST_F(RtpTransceiverTestForHeaderExtensions,ReturnsNegotiatedHdrExtsSecondTime)393 TEST_F(RtpTransceiverTestForHeaderExtensions,
394        ReturnsNegotiatedHdrExtsSecondTime) {
395   EXPECT_CALL(*receiver_.get(), Stop());
396   EXPECT_CALL(*receiver_.get(), SetMediaChannel(_));
397   EXPECT_CALL(*sender_.get(), SetTransceiverAsStopped());
398   EXPECT_CALL(*sender_.get(), Stop());
399 
400   cricket::RtpHeaderExtensions extensions = {webrtc::RtpExtension("uri1", 1),
401                                              webrtc::RtpExtension("uri2", 2)};
402   cricket::AudioContentDescription description;
403   description.set_rtp_header_extensions(extensions);
404   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
405 
406   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
407               ElementsAre(RtpHeaderExtensionCapability(
408                               "uri1", 1, RtpTransceiverDirection::kSendRecv),
409                           RtpHeaderExtensionCapability(
410                               "uri2", 2, RtpTransceiverDirection::kSendRecv)));
411 
412   extensions = {webrtc::RtpExtension("uri3", 4),
413                 webrtc::RtpExtension("uri5", 6)};
414   description.set_rtp_header_extensions(extensions);
415   transceiver_->OnNegotiationUpdate(SdpType::kAnswer, &description);
416 
417   EXPECT_THAT(transceiver_->HeaderExtensionsNegotiated(),
418               ElementsAre(RtpHeaderExtensionCapability(
419                               "uri3", 4, RtpTransceiverDirection::kSendRecv),
420                           RtpHeaderExtensionCapability(
421                               "uri5", 6, RtpTransceiverDirection::kSendRecv)));
422 }
423 
424 }  // namespace
425 
426 }  // namespace webrtc
427