1 /*
2  *  Copyright 2016 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 "pc/track_media_info_map.h"
12 
13 #include <initializer_list>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "api/rtp_sender_interface.h"
20 #include "api/transport/rtp/rtp_source.h"
21 #include "media/base/media_channel.h"
22 #include "pc/audio_track.h"
23 #include "pc/test/fake_video_track_source.h"
24 #include "pc/test/mock_rtp_receiver_internal.h"
25 #include "pc/test/mock_rtp_sender_internal.h"
26 #include "pc/video_track.h"
27 #include "rtc_base/ref_count.h"
28 #include "test/gtest.h"
29 
30 namespace webrtc {
31 
32 namespace {
33 
CreateRtpParametersWithSsrcs(std::initializer_list<uint32_t> ssrcs)34 RtpParameters CreateRtpParametersWithSsrcs(
35     std::initializer_list<uint32_t> ssrcs) {
36   RtpParameters params;
37   for (uint32_t ssrc : ssrcs) {
38     RtpEncodingParameters encoding_params;
39     encoding_params.ssrc = ssrc;
40     params.encodings.push_back(encoding_params);
41   }
42   return params;
43 }
44 
CreateMockRtpSender(cricket::MediaType media_type,std::initializer_list<uint32_t> ssrcs,rtc::scoped_refptr<MediaStreamTrackInterface> track)45 rtc::scoped_refptr<MockRtpSenderInternal> CreateMockRtpSender(
46     cricket::MediaType media_type,
47     std::initializer_list<uint32_t> ssrcs,
48     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
49   uint32_t first_ssrc;
50   if (ssrcs.size()) {
51     first_ssrc = *ssrcs.begin();
52   } else {
53     first_ssrc = 0;
54   }
55   rtc::scoped_refptr<MockRtpSenderInternal> sender(
56       new rtc::RefCountedObject<MockRtpSenderInternal>());
57   EXPECT_CALL(*sender, track())
58       .WillRepeatedly(::testing::Return(std::move(track)));
59   EXPECT_CALL(*sender, ssrc()).WillRepeatedly(::testing::Return(first_ssrc));
60   EXPECT_CALL(*sender, media_type())
61       .WillRepeatedly(::testing::Return(media_type));
62   EXPECT_CALL(*sender, GetParameters())
63       .WillRepeatedly(::testing::Return(CreateRtpParametersWithSsrcs(ssrcs)));
64   EXPECT_CALL(*sender, AttachmentId()).WillRepeatedly(::testing::Return(1));
65   return sender;
66 }
67 
CreateMockRtpReceiver(cricket::MediaType media_type,std::initializer_list<uint32_t> ssrcs,rtc::scoped_refptr<MediaStreamTrackInterface> track)68 rtc::scoped_refptr<MockRtpReceiverInternal> CreateMockRtpReceiver(
69     cricket::MediaType media_type,
70     std::initializer_list<uint32_t> ssrcs,
71     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
72   rtc::scoped_refptr<MockRtpReceiverInternal> receiver(
73       new rtc::RefCountedObject<MockRtpReceiverInternal>());
74   EXPECT_CALL(*receiver, track())
75       .WillRepeatedly(::testing::Return(std::move(track)));
76   EXPECT_CALL(*receiver, media_type())
77       .WillRepeatedly(::testing::Return(media_type));
78   EXPECT_CALL(*receiver, GetParameters())
79       .WillRepeatedly(::testing::Return(CreateRtpParametersWithSsrcs(ssrcs)));
80   EXPECT_CALL(*receiver, AttachmentId()).WillRepeatedly(::testing::Return(1));
81   return receiver;
82 }
83 
84 class TrackMediaInfoMapTest : public ::testing::Test {
85  public:
TrackMediaInfoMapTest()86   TrackMediaInfoMapTest() : TrackMediaInfoMapTest(true) {}
87 
TrackMediaInfoMapTest(bool use_current_thread)88   explicit TrackMediaInfoMapTest(bool use_current_thread)
89       : voice_media_info_(new cricket::VoiceMediaInfo()),
90         video_media_info_(new cricket::VideoMediaInfo()),
91         local_audio_track_(AudioTrack::Create("LocalAudioTrack", nullptr)),
92         remote_audio_track_(AudioTrack::Create("RemoteAudioTrack", nullptr)),
93         local_video_track_(VideoTrack::Create(
94             "LocalVideoTrack",
95             FakeVideoTrackSource::Create(false),
96             use_current_thread ? rtc::Thread::Current() : nullptr)),
97         remote_video_track_(VideoTrack::Create(
98             "RemoteVideoTrack",
99             FakeVideoTrackSource::Create(false),
100             use_current_thread ? rtc::Thread::Current() : nullptr)) {}
101 
~TrackMediaInfoMapTest()102   ~TrackMediaInfoMapTest() {
103     // If we have a map the ownership has been passed to the map, only delete if
104     // |CreateMap| has not been called.
105     if (!map_) {
106       delete voice_media_info_;
107       delete video_media_info_;
108     }
109   }
110 
AddRtpSenderWithSsrcs(std::initializer_list<uint32_t> ssrcs,MediaStreamTrackInterface * local_track)111   void AddRtpSenderWithSsrcs(std::initializer_list<uint32_t> ssrcs,
112                              MediaStreamTrackInterface* local_track) {
113     rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockRtpSender(
114         local_track->kind() == MediaStreamTrackInterface::kAudioKind
115             ? cricket::MEDIA_TYPE_AUDIO
116             : cricket::MEDIA_TYPE_VIDEO,
117         ssrcs, local_track);
118     rtp_senders_.push_back(rtp_sender);
119 
120     if (local_track->kind() == MediaStreamTrackInterface::kAudioKind) {
121       cricket::VoiceSenderInfo voice_sender_info;
122       size_t i = 0;
123       for (uint32_t ssrc : ssrcs) {
124         voice_sender_info.local_stats.push_back(cricket::SsrcSenderInfo());
125         voice_sender_info.local_stats[i++].ssrc = ssrc;
126       }
127       voice_media_info_->senders.push_back(voice_sender_info);
128     } else {
129       cricket::VideoSenderInfo video_sender_info;
130       size_t i = 0;
131       for (uint32_t ssrc : ssrcs) {
132         video_sender_info.local_stats.push_back(cricket::SsrcSenderInfo());
133         video_sender_info.local_stats[i++].ssrc = ssrc;
134       }
135       video_media_info_->senders.push_back(video_sender_info);
136       video_media_info_->aggregated_senders.push_back(video_sender_info);
137     }
138   }
139 
AddRtpReceiverWithSsrcs(std::initializer_list<uint32_t> ssrcs,MediaStreamTrackInterface * remote_track)140   void AddRtpReceiverWithSsrcs(std::initializer_list<uint32_t> ssrcs,
141                                MediaStreamTrackInterface* remote_track) {
142     auto rtp_receiver = CreateMockRtpReceiver(
143         remote_track->kind() == MediaStreamTrackInterface::kAudioKind
144             ? cricket::MEDIA_TYPE_AUDIO
145             : cricket::MEDIA_TYPE_VIDEO,
146         ssrcs, remote_track);
147     rtp_receivers_.push_back(rtp_receiver);
148 
149     if (remote_track->kind() == MediaStreamTrackInterface::kAudioKind) {
150       cricket::VoiceReceiverInfo voice_receiver_info;
151       size_t i = 0;
152       for (uint32_t ssrc : ssrcs) {
153         voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo());
154         voice_receiver_info.local_stats[i++].ssrc = ssrc;
155       }
156       voice_media_info_->receivers.push_back(voice_receiver_info);
157     } else {
158       cricket::VideoReceiverInfo video_receiver_info;
159       size_t i = 0;
160       for (uint32_t ssrc : ssrcs) {
161         video_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo());
162         video_receiver_info.local_stats[i++].ssrc = ssrc;
163       }
164       video_media_info_->receivers.push_back(video_receiver_info);
165     }
166   }
167 
CreateMap()168   void CreateMap() {
169     RTC_DCHECK(!map_);
170     map_.reset(new TrackMediaInfoMap(
171         std::unique_ptr<cricket::VoiceMediaInfo>(voice_media_info_),
172         std::unique_ptr<cricket::VideoMediaInfo>(video_media_info_),
173         rtp_senders_, rtp_receivers_));
174   }
175 
176  protected:
177   cricket::VoiceMediaInfo* voice_media_info_;
178   cricket::VideoMediaInfo* video_media_info_;
179   std::vector<rtc::scoped_refptr<RtpSenderInternal>> rtp_senders_;
180   std::vector<rtc::scoped_refptr<RtpReceiverInternal>> rtp_receivers_;
181   std::unique_ptr<TrackMediaInfoMap> map_;
182   rtc::scoped_refptr<AudioTrack> local_audio_track_;
183   rtc::scoped_refptr<AudioTrack> remote_audio_track_;
184   rtc::scoped_refptr<VideoTrack> local_video_track_;
185   rtc::scoped_refptr<VideoTrack> remote_video_track_;
186 };
187 
188 }  // namespace
189 
TEST_F(TrackMediaInfoMapTest,SingleSenderReceiverPerTrackWithOneSsrc)190 TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithOneSsrc) {
191   AddRtpSenderWithSsrcs({1}, local_audio_track_);
192   AddRtpReceiverWithSsrcs({2}, remote_audio_track_);
193   AddRtpSenderWithSsrcs({3}, local_video_track_);
194   AddRtpReceiverWithSsrcs({4}, remote_video_track_);
195   CreateMap();
196 
197   // Local audio track <-> RTP audio sender
198   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
199   EXPECT_EQ(
200       *map_->GetVoiceSenderInfos(*local_audio_track_),
201       std::vector<cricket::VoiceSenderInfo*>({&voice_media_info_->senders[0]}));
202   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
203             local_audio_track_.get());
204 
205   // Remote audio track <-> RTP audio receiver
206   EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_),
207             &voice_media_info_->receivers[0]);
208   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]),
209             remote_audio_track_.get());
210 
211   // Local video track <-> RTP video sender
212   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
213   EXPECT_EQ(
214       *map_->GetVideoSenderInfos(*local_video_track_),
215       std::vector<cricket::VideoSenderInfo*>({&video_media_info_->senders[0]}));
216   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
217             local_video_track_.get());
218 
219   // Remote video track <-> RTP video receiver
220   EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_),
221             &video_media_info_->receivers[0]);
222   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]),
223             remote_video_track_.get());
224 }
225 
TEST_F(TrackMediaInfoMapTest,SingleSenderReceiverPerTrackWithMissingSsrc)226 TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithMissingSsrc) {
227   AddRtpSenderWithSsrcs({}, local_audio_track_);
228   AddRtpSenderWithSsrcs({}, local_video_track_);
229   AddRtpReceiverWithSsrcs({}, remote_audio_track_);
230   AddRtpReceiverWithSsrcs({}, remote_video_track_);
231   CreateMap();
232 
233   EXPECT_FALSE(map_->GetVoiceSenderInfos(*local_audio_track_));
234   EXPECT_FALSE(map_->GetVideoSenderInfos(*local_video_track_));
235   EXPECT_FALSE(map_->GetVoiceReceiverInfo(*remote_audio_track_));
236   EXPECT_FALSE(map_->GetVideoReceiverInfo(*remote_video_track_));
237 }
238 
TEST_F(TrackMediaInfoMapTest,SingleSenderReceiverPerTrackWithAudioAndVideoUseSameSsrc)239 TEST_F(TrackMediaInfoMapTest,
240        SingleSenderReceiverPerTrackWithAudioAndVideoUseSameSsrc) {
241   AddRtpSenderWithSsrcs({1}, local_audio_track_);
242   AddRtpReceiverWithSsrcs({2}, remote_audio_track_);
243   AddRtpSenderWithSsrcs({1}, local_video_track_);
244   AddRtpReceiverWithSsrcs({2}, remote_video_track_);
245   CreateMap();
246 
247   // Local audio track <-> RTP audio sender
248   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
249   EXPECT_EQ(
250       *map_->GetVoiceSenderInfos(*local_audio_track_),
251       std::vector<cricket::VoiceSenderInfo*>({&voice_media_info_->senders[0]}));
252   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
253             local_audio_track_.get());
254 
255   // Remote audio track <-> RTP audio receiver
256   EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_),
257             &voice_media_info_->receivers[0]);
258   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]),
259             remote_audio_track_.get());
260 
261   // Local video track <-> RTP video sender
262   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
263   EXPECT_EQ(
264       *map_->GetVideoSenderInfos(*local_video_track_),
265       std::vector<cricket::VideoSenderInfo*>({&video_media_info_->senders[0]}));
266   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
267             local_video_track_.get());
268 
269   // Remote video track <-> RTP video receiver
270   EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_),
271             &video_media_info_->receivers[0]);
272   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]),
273             remote_video_track_.get());
274 }
275 
TEST_F(TrackMediaInfoMapTest,SingleMultiSsrcSenderPerTrack)276 TEST_F(TrackMediaInfoMapTest, SingleMultiSsrcSenderPerTrack) {
277   AddRtpSenderWithSsrcs({1, 2}, local_audio_track_);
278   AddRtpSenderWithSsrcs({3, 4}, local_video_track_);
279   CreateMap();
280 
281   // Local audio track <-> RTP audio senders
282   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
283   EXPECT_EQ(
284       *map_->GetVoiceSenderInfos(*local_audio_track_),
285       std::vector<cricket::VoiceSenderInfo*>({&voice_media_info_->senders[0]}));
286   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
287             local_audio_track_.get());
288 
289   // Local video track <-> RTP video senders
290   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
291   EXPECT_EQ(
292       *map_->GetVideoSenderInfos(*local_video_track_),
293       std::vector<cricket::VideoSenderInfo*>({&video_media_info_->senders[0]}));
294   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
295             local_video_track_.get());
296 }
297 
TEST_F(TrackMediaInfoMapTest,MultipleOneSsrcSendersPerTrack)298 TEST_F(TrackMediaInfoMapTest, MultipleOneSsrcSendersPerTrack) {
299   AddRtpSenderWithSsrcs({1}, local_audio_track_);
300   AddRtpSenderWithSsrcs({2}, local_audio_track_);
301   AddRtpSenderWithSsrcs({3}, local_video_track_);
302   AddRtpSenderWithSsrcs({4}, local_video_track_);
303   CreateMap();
304 
305   // Local audio track <-> RTP audio senders
306   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
307   EXPECT_EQ(
308       *map_->GetVoiceSenderInfos(*local_audio_track_),
309       std::vector<cricket::VoiceSenderInfo*>(
310           {&voice_media_info_->senders[0], &voice_media_info_->senders[1]}));
311   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
312             local_audio_track_.get());
313   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]),
314             local_audio_track_.get());
315 
316   // Local video track <-> RTP video senders
317   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
318   EXPECT_EQ(
319       *map_->GetVideoSenderInfos(*local_video_track_),
320       std::vector<cricket::VideoSenderInfo*>(
321           {&video_media_info_->senders[0], &video_media_info_->senders[1]}));
322   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
323             local_video_track_.get());
324   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]),
325             local_video_track_.get());
326 }
327 
TEST_F(TrackMediaInfoMapTest,MultipleMultiSsrcSendersPerTrack)328 TEST_F(TrackMediaInfoMapTest, MultipleMultiSsrcSendersPerTrack) {
329   AddRtpSenderWithSsrcs({1, 2}, local_audio_track_);
330   AddRtpSenderWithSsrcs({3, 4}, local_audio_track_);
331   AddRtpSenderWithSsrcs({5, 6}, local_video_track_);
332   AddRtpSenderWithSsrcs({7, 8}, local_video_track_);
333   CreateMap();
334 
335   // Local audio track <-> RTP audio senders
336   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
337   EXPECT_EQ(
338       *map_->GetVoiceSenderInfos(*local_audio_track_),
339       std::vector<cricket::VoiceSenderInfo*>(
340           {&voice_media_info_->senders[0], &voice_media_info_->senders[1]}));
341   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
342             local_audio_track_.get());
343   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]),
344             local_audio_track_.get());
345 
346   // Local video track <-> RTP video senders
347   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
348   EXPECT_EQ(
349       *map_->GetVideoSenderInfos(*local_video_track_),
350       std::vector<cricket::VideoSenderInfo*>(
351           {&video_media_info_->senders[0], &video_media_info_->senders[1]}));
352   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
353             local_video_track_.get());
354   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]),
355             local_video_track_.get());
356 }
357 
358 // SSRCs can be reused for send and receive in loopback.
TEST_F(TrackMediaInfoMapTest,SingleSenderReceiverPerTrackWithSsrcNotUnique)359 TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithSsrcNotUnique) {
360   AddRtpSenderWithSsrcs({1}, local_audio_track_);
361   AddRtpReceiverWithSsrcs({1}, remote_audio_track_);
362   AddRtpSenderWithSsrcs({2}, local_video_track_);
363   AddRtpReceiverWithSsrcs({2}, remote_video_track_);
364   CreateMap();
365 
366   // Local audio track <-> RTP audio senders
367   ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
368   EXPECT_EQ(
369       *map_->GetVoiceSenderInfos(*local_audio_track_),
370       std::vector<cricket::VoiceSenderInfo*>({&voice_media_info_->senders[0]}));
371   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
372             local_audio_track_.get());
373 
374   // Remote audio track <-> RTP audio receiver
375   EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_),
376             &voice_media_info_->receivers[0]);
377   EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]),
378             remote_audio_track_.get());
379 
380   // Local video track <-> RTP video senders
381   ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
382   EXPECT_EQ(
383       *map_->GetVideoSenderInfos(*local_video_track_),
384       std::vector<cricket::VideoSenderInfo*>({&video_media_info_->senders[0]}));
385   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
386             local_video_track_.get());
387 
388   // Remote video track <-> RTP video receiver
389   EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_),
390             &video_media_info_->receivers[0]);
391   EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]),
392             remote_video_track_.get());
393 }
394 
TEST_F(TrackMediaInfoMapTest,SsrcLookupFunction)395 TEST_F(TrackMediaInfoMapTest, SsrcLookupFunction) {
396   AddRtpSenderWithSsrcs({1}, local_audio_track_);
397   AddRtpReceiverWithSsrcs({2}, remote_audio_track_);
398   AddRtpSenderWithSsrcs({3}, local_video_track_);
399   AddRtpReceiverWithSsrcs({4}, remote_video_track_);
400   CreateMap();
401   EXPECT_TRUE(map_->GetVoiceSenderInfoBySsrc(1));
402   EXPECT_TRUE(map_->GetVoiceReceiverInfoBySsrc(2));
403   EXPECT_TRUE(map_->GetVideoSenderInfoBySsrc(3));
404   EXPECT_TRUE(map_->GetVideoReceiverInfoBySsrc(4));
405   EXPECT_FALSE(map_->GetVoiceSenderInfoBySsrc(2));
406   EXPECT_FALSE(map_->GetVoiceSenderInfoBySsrc(1024));
407 }
408 
TEST_F(TrackMediaInfoMapTest,GetAttachmentIdByTrack)409 TEST_F(TrackMediaInfoMapTest, GetAttachmentIdByTrack) {
410   AddRtpSenderWithSsrcs({1}, local_audio_track_);
411   CreateMap();
412   EXPECT_EQ(rtp_senders_[0]->AttachmentId(),
413             map_->GetAttachmentIdByTrack(local_audio_track_));
414   EXPECT_EQ(absl::nullopt, map_->GetAttachmentIdByTrack(local_video_track_));
415 }
416 
417 // Death tests.
418 // Disabled on Android because death tests misbehave on Android, see
419 // base/test/gtest_util.h.
420 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
421 
422 class TrackMediaInfoMapDeathTest : public TrackMediaInfoMapTest {
423  public:
TrackMediaInfoMapDeathTest()424   TrackMediaInfoMapDeathTest() : TrackMediaInfoMapTest(false) {}
425 };
426 
TEST_F(TrackMediaInfoMapDeathTest,MultipleOneSsrcReceiversPerTrack)427 TEST_F(TrackMediaInfoMapDeathTest, MultipleOneSsrcReceiversPerTrack) {
428   AddRtpReceiverWithSsrcs({1}, remote_audio_track_);
429   AddRtpReceiverWithSsrcs({2}, remote_audio_track_);
430   AddRtpReceiverWithSsrcs({3}, remote_video_track_);
431   AddRtpReceiverWithSsrcs({4}, remote_video_track_);
432   EXPECT_DEATH(CreateMap(), "");
433 }
434 
TEST_F(TrackMediaInfoMapDeathTest,MultipleMultiSsrcReceiversPerTrack)435 TEST_F(TrackMediaInfoMapDeathTest, MultipleMultiSsrcReceiversPerTrack) {
436   AddRtpReceiverWithSsrcs({1, 2}, remote_audio_track_);
437   AddRtpReceiverWithSsrcs({3, 4}, remote_audio_track_);
438   AddRtpReceiverWithSsrcs({5, 6}, remote_video_track_);
439   AddRtpReceiverWithSsrcs({7, 8}, remote_video_track_);
440   EXPECT_DEATH(CreateMap(), "");
441 }
442 
443 #endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
444 
445 }  // namespace webrtc
446