TrackMediaInfoMap: Allow same SSRC for send and receive side.

Running video loopback on https://appr.tc/ revealed that it is possible
to use the same SSRC for a local and remote audio or video track. This
caused a DCHECK crash. The constructor of TrackMediaInfoMap is updated
to support this mapping and the unittest is updated (moved and modified
a test from being a death test to being a non-death test).

I've verified that this fixes the bug.

BUG=chromium:693087

Review-Url: https://codereview.webrtc.org/2703783002
Cr-Commit-Position: refs/heads/master@{#16713}
diff --git a/webrtc/pc/trackmediainfomap.cc b/webrtc/pc/trackmediainfomap.cc
index d296c7f..33880b9 100644
--- a/webrtc/pc/trackmediainfomap.cc
+++ b/webrtc/pc/trackmediainfomap.cc
@@ -31,10 +31,14 @@
 void GetAudioAndVideoTrackBySsrc(
     const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
     const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers,
-    std::map<uint32_t, AudioTrackInterface*>* audio_track_by_ssrc,
-    std::map<uint32_t, VideoTrackInterface*>* video_track_by_ssrc) {
-  RTC_DCHECK(audio_track_by_ssrc->empty());
-  RTC_DCHECK(video_track_by_ssrc->empty());
+    std::map<uint32_t, AudioTrackInterface*>* local_audio_track_by_ssrc,
+    std::map<uint32_t, VideoTrackInterface*>* local_video_track_by_ssrc,
+    std::map<uint32_t, AudioTrackInterface*>* remote_audio_track_by_ssrc,
+    std::map<uint32_t, VideoTrackInterface*>* remote_video_track_by_ssrc) {
+  RTC_DCHECK(local_audio_track_by_ssrc->empty());
+  RTC_DCHECK(local_video_track_by_ssrc->empty());
+  RTC_DCHECK(remote_audio_track_by_ssrc->empty());
+  RTC_DCHECK(remote_video_track_by_ssrc->empty());
   // TODO(hbos): RTP senders/receivers uses a proxy to the signaling thread, and
   // our sender/receiver implementations invokes on the worker thread. (This
   // means one thread jump if on signaling thread and two thread jumps if on any
@@ -53,13 +57,15 @@
     uint32_t ssrc = rtp_sender->ssrc();
     if (ssrc != 0) {
       if (media_type == cricket::MEDIA_TYPE_AUDIO) {
-        RTC_DCHECK(audio_track_by_ssrc->find(ssrc) ==
-                   audio_track_by_ssrc->end());
-        (*audio_track_by_ssrc)[ssrc] = static_cast<AudioTrackInterface*>(track);
+        RTC_DCHECK(local_audio_track_by_ssrc->find(ssrc) ==
+                   local_audio_track_by_ssrc->end());
+        (*local_audio_track_by_ssrc)[ssrc] =
+            static_cast<AudioTrackInterface*>(track);
       } else {
-        RTC_DCHECK(video_track_by_ssrc->find(ssrc) ==
-                   video_track_by_ssrc->end());
-        (*video_track_by_ssrc)[ssrc] = static_cast<VideoTrackInterface*>(track);
+        RTC_DCHECK(local_video_track_by_ssrc->find(ssrc) ==
+                   local_video_track_by_ssrc->end());
+        (*local_video_track_by_ssrc)[ssrc] =
+            static_cast<VideoTrackInterface*>(track);
       }
     }
   }
@@ -77,14 +83,14 @@
         continue;
       }
       if (media_type == cricket::MEDIA_TYPE_AUDIO) {
-        RTC_DCHECK(audio_track_by_ssrc->find(*encoding.ssrc) ==
-                   audio_track_by_ssrc->end());
-        (*audio_track_by_ssrc)[*encoding.ssrc] =
+        RTC_DCHECK(remote_audio_track_by_ssrc->find(*encoding.ssrc) ==
+                   remote_audio_track_by_ssrc->end());
+        (*remote_audio_track_by_ssrc)[*encoding.ssrc] =
             static_cast<AudioTrackInterface*>(track);
       } else {
-        RTC_DCHECK(video_track_by_ssrc->find(*encoding.ssrc) ==
-                   video_track_by_ssrc->end());
-        (*video_track_by_ssrc)[*encoding.ssrc] =
+        RTC_DCHECK(remote_video_track_by_ssrc->find(*encoding.ssrc) ==
+                   remote_video_track_by_ssrc->end());
+        (*remote_video_track_by_ssrc)[*encoding.ssrc] =
             static_cast<VideoTrackInterface*>(track);
       }
     }
@@ -100,14 +106,20 @@
     const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers)
     : voice_media_info_(std::move(voice_media_info)),
       video_media_info_(std::move(video_media_info)) {
-  std::map<uint32_t, AudioTrackInterface*> audio_track_by_ssrc;
-  std::map<uint32_t, VideoTrackInterface*> video_track_by_ssrc;
-  GetAudioAndVideoTrackBySsrc(rtp_senders, rtp_receivers, &audio_track_by_ssrc,
-                              &video_track_by_ssrc);
+  std::map<uint32_t, AudioTrackInterface*> local_audio_track_by_ssrc;
+  std::map<uint32_t, VideoTrackInterface*> local_video_track_by_ssrc;
+  std::map<uint32_t, AudioTrackInterface*> remote_audio_track_by_ssrc;
+  std::map<uint32_t, VideoTrackInterface*> remote_video_track_by_ssrc;
+  GetAudioAndVideoTrackBySsrc(rtp_senders,
+                              rtp_receivers,
+                              &local_audio_track_by_ssrc,
+                              &local_video_track_by_ssrc,
+                              &remote_audio_track_by_ssrc,
+                              &remote_video_track_by_ssrc);
   if (voice_media_info_) {
     for (auto& sender_info : voice_media_info_->senders) {
       AudioTrackInterface* associated_track =
-          FindValueOrNull(audio_track_by_ssrc, sender_info.ssrc());
+          FindValueOrNull(local_audio_track_by_ssrc, sender_info.ssrc());
       if (associated_track) {
         // One sender is associated with at most one track.
         // One track may be associated with multiple senders.
@@ -117,7 +129,7 @@
     }
     for (auto& receiver_info : voice_media_info_->receivers) {
       AudioTrackInterface* associated_track =
-          FindValueOrNull(audio_track_by_ssrc, receiver_info.ssrc());
+          FindValueOrNull(remote_audio_track_by_ssrc, receiver_info.ssrc());
       if (associated_track) {
         // One receiver is associated with at most one track, which is uniquely
         // associated with that receiver.
@@ -131,7 +143,7 @@
   if (video_media_info_) {
     for (auto& sender_info : video_media_info_->senders) {
       VideoTrackInterface* associated_track =
-          FindValueOrNull(video_track_by_ssrc, sender_info.ssrc());
+          FindValueOrNull(local_video_track_by_ssrc, sender_info.ssrc());
       if (associated_track) {
         // One sender is associated with at most one track.
         // One track may be associated with multiple senders.
@@ -141,7 +153,7 @@
     }
     for (auto& receiver_info : video_media_info_->receivers) {
       VideoTrackInterface* associated_track =
-          FindValueOrNull(video_track_by_ssrc, receiver_info.ssrc());
+          FindValueOrNull(remote_video_track_by_ssrc, receiver_info.ssrc());
       if (associated_track) {
         // One receiver is associated with at most one track, which is uniquely
         // associated with that receiver.
diff --git a/webrtc/pc/trackmediainfomap_unittest.cc b/webrtc/pc/trackmediainfomap_unittest.cc
index 2786214..0743680 100644
--- a/webrtc/pc/trackmediainfomap_unittest.cc
+++ b/webrtc/pc/trackmediainfomap_unittest.cc
@@ -345,6 +345,43 @@
             local_video_track_.get());
 }
 
+// SSRCs can be reused for send and receive in loopback.
+TEST_F(TrackMediaInfoMapTest, SingleSenderReceiverPerTrackWithSsrcNotUnique) {
+  AddRtpSenderWithSsrcs({1}, local_audio_track_);
+  AddRtpReceiverWithSsrcs({1}, remote_audio_track_);
+  AddRtpSenderWithSsrcs({2}, local_video_track_);
+  AddRtpReceiverWithSsrcs({2}, remote_video_track_);
+  CreateMap();
+
+  // Local audio track <-> RTP audio senders
+  ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_));
+  EXPECT_EQ(
+      *map_->GetVoiceSenderInfos(*local_audio_track_),
+      std::vector<cricket::VoiceSenderInfo*>({&voice_media_info_->senders[0]}));
+  EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]),
+            local_audio_track_.get());
+
+  // Remote audio track <-> RTP audio receiver
+  EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_),
+            &voice_media_info_->receivers[0]);
+  EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]),
+            remote_audio_track_.get());
+
+  // Local video track <-> RTP video senders
+  ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_));
+  EXPECT_EQ(
+      *map_->GetVideoSenderInfos(*local_video_track_),
+      std::vector<cricket::VideoSenderInfo*>({&video_media_info_->senders[0]}));
+  EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]),
+            local_video_track_.get());
+
+  // Remote video track <-> RTP video receiver
+  EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_),
+            &video_media_info_->receivers[0]);
+  EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]),
+            remote_video_track_.get());
+}
+
 // Death tests.
 // Disabled on Android because death tests misbehave on Android, see
 // base/test/gtest_util.h.
@@ -368,15 +405,6 @@
   EXPECT_DEATH(CreateMap(), "");
 }
 
-TEST_F(TrackMediaInfoMapDeathTest,
-       SingleSenderReceiverPerTrackWithSsrcNotUnique) {
-  AddRtpSenderWithSsrcs({1}, local_audio_track_);
-  AddRtpReceiverWithSsrcs({1}, remote_audio_track_);
-  AddRtpSenderWithSsrcs({2}, local_video_track_);
-  AddRtpReceiverWithSsrcs({2}, remote_video_track_);
-  EXPECT_DEATH(CreateMap(), "");
-}
-
 #endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
 
 }  // namespace webrtc