blob: 781737a085f6551e119fca0844d3dc91aaf8a8d1 [file] [log] [blame]
hbos1f8239c2017-01-16 04:24:10 -08001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/track_media_info_map.h"
hbos1f8239c2017-01-16 04:24:10 -080012
Steve Anton5dfde182018-02-06 10:34:40 -080013#include <string>
hbos1f8239c2017-01-16 04:24:10 -080014#include <utility>
15
16namespace webrtc {
17
18namespace {
19
deadbeef804c1af2017-02-11 19:07:31 -080020template <typename K, typename V>
hbos1f8239c2017-01-16 04:24:10 -080021V FindValueOrNull(const std::map<K, V>& map, const K& key) {
22 auto it = map.find(key);
23 return (it != map.end()) ? it->second : nullptr;
24}
25
deadbeef804c1af2017-02-11 19:07:31 -080026template <typename K, typename V>
hbos1f8239c2017-01-16 04:24:10 -080027const V* FindAddressOrNull(const std::map<K, V>& map, const K& key) {
28 auto it = map.find(key);
29 return (it != map.end()) ? &it->second : nullptr;
30}
31
32void GetAudioAndVideoTrackBySsrc(
Steve Anton57858b32018-02-15 15:19:50 -080033 const std::vector<rtc::scoped_refptr<RtpSenderInternal>>& rtp_senders,
34 const std::vector<rtc::scoped_refptr<RtpReceiverInternal>>& rtp_receivers,
hbosfe90ad12017-02-20 02:05:13 -080035 std::map<uint32_t, AudioTrackInterface*>* local_audio_track_by_ssrc,
36 std::map<uint32_t, VideoTrackInterface*>* local_video_track_by_ssrc,
37 std::map<uint32_t, AudioTrackInterface*>* remote_audio_track_by_ssrc,
zhihuangf8164932017-05-19 13:09:47 -070038 std::map<uint32_t, VideoTrackInterface*>* remote_video_track_by_ssrc,
39 AudioTrackInterface** unsignaled_audio_track,
40 VideoTrackInterface** unsignaled_video_track) {
hbosfe90ad12017-02-20 02:05:13 -080041 RTC_DCHECK(local_audio_track_by_ssrc->empty());
42 RTC_DCHECK(local_video_track_by_ssrc->empty());
43 RTC_DCHECK(remote_audio_track_by_ssrc->empty());
44 RTC_DCHECK(remote_video_track_by_ssrc->empty());
hbos1f8239c2017-01-16 04:24:10 -080045 // TODO(hbos): RTP senders/receivers uses a proxy to the signaling thread, and
46 // our sender/receiver implementations invokes on the worker thread. (This
47 // means one thread jump if on signaling thread and two thread jumps if on any
48 // other threads). Is there a way to avoid thread jump(s) on a per
49 // sender/receiver, per method basis?
Mirko Bonadei739baf02019-01-27 17:29:42 +010050 for (const auto& rtp_sender : rtp_senders) {
hbos1f8239c2017-01-16 04:24:10 -080051 cricket::MediaType media_type = rtp_sender->media_type();
52 MediaStreamTrackInterface* track = rtp_sender->track();
53 if (!track) {
54 continue;
55 }
deadbeef804c1af2017-02-11 19:07:31 -080056 RTC_DCHECK_EQ(track->kind(), media_type == cricket::MEDIA_TYPE_AUDIO
57 ? MediaStreamTrackInterface::kAudioKind
58 : MediaStreamTrackInterface::kVideoKind);
hbos1f8239c2017-01-16 04:24:10 -080059 // TODO(deadbeef): |ssrc| should be removed in favor of |GetParameters|.
60 uint32_t ssrc = rtp_sender->ssrc();
61 if (ssrc != 0) {
62 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbosfe90ad12017-02-20 02:05:13 -080063 RTC_DCHECK(local_audio_track_by_ssrc->find(ssrc) ==
64 local_audio_track_by_ssrc->end());
65 (*local_audio_track_by_ssrc)[ssrc] =
66 static_cast<AudioTrackInterface*>(track);
hbos1f8239c2017-01-16 04:24:10 -080067 } else {
hbosfe90ad12017-02-20 02:05:13 -080068 RTC_DCHECK(local_video_track_by_ssrc->find(ssrc) ==
69 local_video_track_by_ssrc->end());
70 (*local_video_track_by_ssrc)[ssrc] =
71 static_cast<VideoTrackInterface*>(track);
hbos1f8239c2017-01-16 04:24:10 -080072 }
73 }
74 }
Mirko Bonadei739baf02019-01-27 17:29:42 +010075 for (const auto& rtp_receiver : rtp_receivers) {
hbos1f8239c2017-01-16 04:24:10 -080076 cricket::MediaType media_type = rtp_receiver->media_type();
77 MediaStreamTrackInterface* track = rtp_receiver->track();
78 RTC_DCHECK(track);
deadbeef804c1af2017-02-11 19:07:31 -080079 RTC_DCHECK_EQ(track->kind(), media_type == cricket::MEDIA_TYPE_AUDIO
80 ? MediaStreamTrackInterface::kAudioKind
81 : MediaStreamTrackInterface::kVideoKind);
hbos1f8239c2017-01-16 04:24:10 -080082 RtpParameters params = rtp_receiver->GetParameters();
83 for (const RtpEncodingParameters& encoding : params.encodings) {
84 if (!encoding.ssrc) {
zhihuangf8164932017-05-19 13:09:47 -070085 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
86 *unsignaled_audio_track = static_cast<AudioTrackInterface*>(track);
87 } else {
88 RTC_DCHECK(media_type == cricket::MEDIA_TYPE_VIDEO);
89 *unsignaled_video_track = static_cast<VideoTrackInterface*>(track);
90 }
hbos1f8239c2017-01-16 04:24:10 -080091 continue;
92 }
93 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbosfe90ad12017-02-20 02:05:13 -080094 RTC_DCHECK(remote_audio_track_by_ssrc->find(*encoding.ssrc) ==
95 remote_audio_track_by_ssrc->end());
96 (*remote_audio_track_by_ssrc)[*encoding.ssrc] =
hbos1f8239c2017-01-16 04:24:10 -080097 static_cast<AudioTrackInterface*>(track);
98 } else {
hbosfe90ad12017-02-20 02:05:13 -080099 RTC_DCHECK(remote_video_track_by_ssrc->find(*encoding.ssrc) ==
100 remote_video_track_by_ssrc->end());
101 (*remote_video_track_by_ssrc)[*encoding.ssrc] =
hbos1f8239c2017-01-16 04:24:10 -0800102 static_cast<VideoTrackInterface*>(track);
103 }
104 }
105 }
106}
107
108} // namespace
109
110TrackMediaInfoMap::TrackMediaInfoMap(
111 std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info,
112 std::unique_ptr<cricket::VideoMediaInfo> video_media_info,
Steve Anton57858b32018-02-15 15:19:50 -0800113 const std::vector<rtc::scoped_refptr<RtpSenderInternal>>& rtp_senders,
114 const std::vector<rtc::scoped_refptr<RtpReceiverInternal>>& rtp_receivers)
hbos1f8239c2017-01-16 04:24:10 -0800115 : voice_media_info_(std::move(voice_media_info)),
116 video_media_info_(std::move(video_media_info)) {
hbosfe90ad12017-02-20 02:05:13 -0800117 std::map<uint32_t, AudioTrackInterface*> local_audio_track_by_ssrc;
118 std::map<uint32_t, VideoTrackInterface*> local_video_track_by_ssrc;
119 std::map<uint32_t, AudioTrackInterface*> remote_audio_track_by_ssrc;
120 std::map<uint32_t, VideoTrackInterface*> remote_video_track_by_ssrc;
zhihuangf8164932017-05-19 13:09:47 -0700121 AudioTrackInterface* unsignaled_audio_track = nullptr;
122 VideoTrackInterface* unsignaled_video_track = nullptr;
123 GetAudioAndVideoTrackBySsrc(
124 rtp_senders, rtp_receivers, &local_audio_track_by_ssrc,
125 &local_video_track_by_ssrc, &remote_audio_track_by_ssrc,
126 &remote_video_track_by_ssrc, &unsignaled_audio_track,
127 &unsignaled_video_track);
Harald Alvestrandc72af932018-01-11 17:18:19 +0100128
Mirko Bonadei739baf02019-01-27 17:29:42 +0100129 for (const auto& sender : rtp_senders) {
Harald Alvestrandc72af932018-01-11 17:18:19 +0100130 attachment_id_by_track_[sender->track()] = sender->AttachmentId();
131 }
Mirko Bonadei739baf02019-01-27 17:29:42 +0100132 for (const auto& receiver : rtp_receivers) {
Harald Alvestrandc72af932018-01-11 17:18:19 +0100133 attachment_id_by_track_[receiver->track()] = receiver->AttachmentId();
134 }
135
hbos1f8239c2017-01-16 04:24:10 -0800136 if (voice_media_info_) {
137 for (auto& sender_info : voice_media_info_->senders) {
138 AudioTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800139 FindValueOrNull(local_audio_track_by_ssrc, sender_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800140 if (associated_track) {
141 // One sender is associated with at most one track.
142 // One track may be associated with multiple senders.
143 audio_track_by_sender_info_[&sender_info] = associated_track;
144 voice_infos_by_local_track_[associated_track].push_back(&sender_info);
145 }
Harald Alvestrand89061872018-01-02 14:08:34 +0100146 if (sender_info.ssrc() == 0)
147 continue; // Unconnected SSRC. bugs.webrtc.org/8673
148 RTC_CHECK(voice_info_by_sender_ssrc_.count(sender_info.ssrc()) == 0)
149 << "Duplicate voice sender SSRC: " << sender_info.ssrc();
150 voice_info_by_sender_ssrc_[sender_info.ssrc()] = &sender_info;
hbos1f8239c2017-01-16 04:24:10 -0800151 }
152 for (auto& receiver_info : voice_media_info_->receivers) {
153 AudioTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800154 FindValueOrNull(remote_audio_track_by_ssrc, receiver_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800155 if (associated_track) {
156 // One receiver is associated with at most one track, which is uniquely
157 // associated with that receiver.
158 audio_track_by_receiver_info_[&receiver_info] = associated_track;
159 RTC_DCHECK(voice_info_by_remote_track_.find(associated_track) ==
160 voice_info_by_remote_track_.end());
161 voice_info_by_remote_track_[associated_track] = &receiver_info;
zhihuangf8164932017-05-19 13:09:47 -0700162 } else if (unsignaled_audio_track) {
163 audio_track_by_receiver_info_[&receiver_info] = unsignaled_audio_track;
164 voice_info_by_remote_track_[unsignaled_audio_track] = &receiver_info;
hbos1f8239c2017-01-16 04:24:10 -0800165 }
Harald Alvestrand89061872018-01-02 14:08:34 +0100166 RTC_CHECK(voice_info_by_receiver_ssrc_.count(receiver_info.ssrc()) == 0)
167 << "Duplicate voice receiver SSRC: " << receiver_info.ssrc();
168 voice_info_by_receiver_ssrc_[receiver_info.ssrc()] = &receiver_info;
hbos1f8239c2017-01-16 04:24:10 -0800169 }
170 }
171 if (video_media_info_) {
172 for (auto& sender_info : video_media_info_->senders) {
173 VideoTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800174 FindValueOrNull(local_video_track_by_ssrc, sender_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800175 if (associated_track) {
176 // One sender is associated with at most one track.
177 // One track may be associated with multiple senders.
178 video_track_by_sender_info_[&sender_info] = associated_track;
179 video_infos_by_local_track_[associated_track].push_back(&sender_info);
180 }
Harald Alvestrand89061872018-01-02 14:08:34 +0100181 if (sender_info.ssrc() == 0)
182 continue; // Unconnected SSRC. bugs.webrtc.org/8673
183 RTC_DCHECK(video_info_by_sender_ssrc_.count(sender_info.ssrc()) == 0)
184 << "Duplicate video sender SSRC: " << sender_info.ssrc();
185 video_info_by_sender_ssrc_[sender_info.ssrc()] = &sender_info;
hbos1f8239c2017-01-16 04:24:10 -0800186 }
187 for (auto& receiver_info : video_media_info_->receivers) {
188 VideoTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800189 FindValueOrNull(remote_video_track_by_ssrc, receiver_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800190 if (associated_track) {
191 // One receiver is associated with at most one track, which is uniquely
192 // associated with that receiver.
193 video_track_by_receiver_info_[&receiver_info] = associated_track;
194 RTC_DCHECK(video_info_by_remote_track_.find(associated_track) ==
195 video_info_by_remote_track_.end());
196 video_info_by_remote_track_[associated_track] = &receiver_info;
zhihuangf8164932017-05-19 13:09:47 -0700197 } else if (unsignaled_video_track) {
198 video_track_by_receiver_info_[&receiver_info] = unsignaled_video_track;
199 video_info_by_remote_track_[unsignaled_video_track] = &receiver_info;
hbos1f8239c2017-01-16 04:24:10 -0800200 }
Harald Alvestrand89061872018-01-02 14:08:34 +0100201 RTC_DCHECK(video_info_by_receiver_ssrc_.count(receiver_info.ssrc()) == 0)
202 << "Duplicate video receiver SSRC: " << receiver_info.ssrc();
203 video_info_by_receiver_ssrc_[receiver_info.ssrc()] = &receiver_info;
hbos1f8239c2017-01-16 04:24:10 -0800204 }
205 }
206}
207
208const std::vector<cricket::VoiceSenderInfo*>*
209TrackMediaInfoMap::GetVoiceSenderInfos(
210 const AudioTrackInterface& local_audio_track) const {
211 return FindAddressOrNull(voice_infos_by_local_track_, &local_audio_track);
212}
213
214const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfo(
215 const AudioTrackInterface& remote_audio_track) const {
216 return FindValueOrNull(voice_info_by_remote_track_, &remote_audio_track);
217}
218
219const std::vector<cricket::VideoSenderInfo*>*
220TrackMediaInfoMap::GetVideoSenderInfos(
221 const VideoTrackInterface& local_video_track) const {
222 return FindAddressOrNull(video_infos_by_local_track_, &local_video_track);
223}
224
225const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfo(
226 const VideoTrackInterface& remote_video_track) const {
227 return FindValueOrNull(video_info_by_remote_track_, &remote_video_track);
228}
229
Harald Alvestrand89061872018-01-02 14:08:34 +0100230const cricket::VoiceSenderInfo* TrackMediaInfoMap::GetVoiceSenderInfoBySsrc(
231 uint32_t ssrc) const {
232 return FindValueOrNull(voice_info_by_sender_ssrc_, ssrc);
233}
234const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfoBySsrc(
235 uint32_t ssrc) const {
236 return FindValueOrNull(voice_info_by_receiver_ssrc_, ssrc);
237}
238
239const cricket::VideoSenderInfo* TrackMediaInfoMap::GetVideoSenderInfoBySsrc(
240 uint32_t ssrc) const {
241 return FindValueOrNull(video_info_by_sender_ssrc_, ssrc);
242}
243
244const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfoBySsrc(
245 uint32_t ssrc) const {
246 return FindValueOrNull(video_info_by_receiver_ssrc_, ssrc);
247}
248
hbos1f8239c2017-01-16 04:24:10 -0800249rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack(
250 const cricket::VoiceSenderInfo& voice_sender_info) const {
251 return FindValueOrNull(audio_track_by_sender_info_, &voice_sender_info);
252}
253
254rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack(
255 const cricket::VoiceReceiverInfo& voice_receiver_info) const {
256 return FindValueOrNull(audio_track_by_receiver_info_, &voice_receiver_info);
257}
258
259rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack(
260 const cricket::VideoSenderInfo& video_sender_info) const {
261 return FindValueOrNull(video_track_by_sender_info_, &video_sender_info);
262}
263
264rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack(
265 const cricket::VideoReceiverInfo& video_receiver_info) const {
266 return FindValueOrNull(video_track_by_receiver_info_, &video_receiver_info);
267}
268
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200269absl::optional<int> TrackMediaInfoMap::GetAttachmentIdByTrack(
Harald Alvestrandc72af932018-01-11 17:18:19 +0100270 const MediaStreamTrackInterface* track) const {
271 auto it = attachment_id_by_track_.find(track);
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200272 return it != attachment_id_by_track_.end() ? absl::optional<int>(it->second)
273 : absl::nullopt;
Harald Alvestrandc72af932018-01-11 17:18:19 +0100274}
275
hbos1f8239c2017-01-16 04:24:10 -0800276} // namespace webrtc