blob: 33880b9380bcf7e7751af58b60331d68c2fb6eb7 [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
deadbeef804c1af2017-02-11 19:07:31 -080011#include "webrtc/pc/trackmediainfomap.h"
hbos1f8239c2017-01-16 04:24:10 -080012
13#include <utility>
14
15namespace webrtc {
16
17namespace {
18
deadbeef804c1af2017-02-11 19:07:31 -080019template <typename K, typename V>
hbos1f8239c2017-01-16 04:24:10 -080020V FindValueOrNull(const std::map<K, V>& map, const K& key) {
21 auto it = map.find(key);
22 return (it != map.end()) ? it->second : nullptr;
23}
24
deadbeef804c1af2017-02-11 19:07:31 -080025template <typename K, typename V>
hbos1f8239c2017-01-16 04:24:10 -080026const V* FindAddressOrNull(const std::map<K, V>& map, const K& key) {
27 auto it = map.find(key);
28 return (it != map.end()) ? &it->second : nullptr;
29}
30
31void GetAudioAndVideoTrackBySsrc(
32 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
33 const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers,
hbosfe90ad12017-02-20 02:05:13 -080034 std::map<uint32_t, AudioTrackInterface*>* local_audio_track_by_ssrc,
35 std::map<uint32_t, VideoTrackInterface*>* local_video_track_by_ssrc,
36 std::map<uint32_t, AudioTrackInterface*>* remote_audio_track_by_ssrc,
37 std::map<uint32_t, VideoTrackInterface*>* remote_video_track_by_ssrc) {
38 RTC_DCHECK(local_audio_track_by_ssrc->empty());
39 RTC_DCHECK(local_video_track_by_ssrc->empty());
40 RTC_DCHECK(remote_audio_track_by_ssrc->empty());
41 RTC_DCHECK(remote_video_track_by_ssrc->empty());
hbos1f8239c2017-01-16 04:24:10 -080042 // TODO(hbos): RTP senders/receivers uses a proxy to the signaling thread, and
43 // our sender/receiver implementations invokes on the worker thread. (This
44 // means one thread jump if on signaling thread and two thread jumps if on any
45 // other threads). Is there a way to avoid thread jump(s) on a per
46 // sender/receiver, per method basis?
47 for (const rtc::scoped_refptr<RtpSenderInterface>& rtp_sender : rtp_senders) {
48 cricket::MediaType media_type = rtp_sender->media_type();
49 MediaStreamTrackInterface* track = rtp_sender->track();
50 if (!track) {
51 continue;
52 }
deadbeef804c1af2017-02-11 19:07:31 -080053 RTC_DCHECK_EQ(track->kind(), media_type == cricket::MEDIA_TYPE_AUDIO
54 ? MediaStreamTrackInterface::kAudioKind
55 : MediaStreamTrackInterface::kVideoKind);
hbos1f8239c2017-01-16 04:24:10 -080056 // TODO(deadbeef): |ssrc| should be removed in favor of |GetParameters|.
57 uint32_t ssrc = rtp_sender->ssrc();
58 if (ssrc != 0) {
59 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbosfe90ad12017-02-20 02:05:13 -080060 RTC_DCHECK(local_audio_track_by_ssrc->find(ssrc) ==
61 local_audio_track_by_ssrc->end());
62 (*local_audio_track_by_ssrc)[ssrc] =
63 static_cast<AudioTrackInterface*>(track);
hbos1f8239c2017-01-16 04:24:10 -080064 } else {
hbosfe90ad12017-02-20 02:05:13 -080065 RTC_DCHECK(local_video_track_by_ssrc->find(ssrc) ==
66 local_video_track_by_ssrc->end());
67 (*local_video_track_by_ssrc)[ssrc] =
68 static_cast<VideoTrackInterface*>(track);
hbos1f8239c2017-01-16 04:24:10 -080069 }
70 }
71 }
72 for (const rtc::scoped_refptr<RtpReceiverInterface>& rtp_receiver :
73 rtp_receivers) {
74 cricket::MediaType media_type = rtp_receiver->media_type();
75 MediaStreamTrackInterface* track = rtp_receiver->track();
76 RTC_DCHECK(track);
deadbeef804c1af2017-02-11 19:07:31 -080077 RTC_DCHECK_EQ(track->kind(), media_type == cricket::MEDIA_TYPE_AUDIO
78 ? MediaStreamTrackInterface::kAudioKind
79 : MediaStreamTrackInterface::kVideoKind);
hbos1f8239c2017-01-16 04:24:10 -080080 RtpParameters params = rtp_receiver->GetParameters();
81 for (const RtpEncodingParameters& encoding : params.encodings) {
82 if (!encoding.ssrc) {
83 continue;
84 }
85 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
hbosfe90ad12017-02-20 02:05:13 -080086 RTC_DCHECK(remote_audio_track_by_ssrc->find(*encoding.ssrc) ==
87 remote_audio_track_by_ssrc->end());
88 (*remote_audio_track_by_ssrc)[*encoding.ssrc] =
hbos1f8239c2017-01-16 04:24:10 -080089 static_cast<AudioTrackInterface*>(track);
90 } else {
hbosfe90ad12017-02-20 02:05:13 -080091 RTC_DCHECK(remote_video_track_by_ssrc->find(*encoding.ssrc) ==
92 remote_video_track_by_ssrc->end());
93 (*remote_video_track_by_ssrc)[*encoding.ssrc] =
hbos1f8239c2017-01-16 04:24:10 -080094 static_cast<VideoTrackInterface*>(track);
95 }
96 }
97 }
98}
99
100} // namespace
101
102TrackMediaInfoMap::TrackMediaInfoMap(
103 std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info,
104 std::unique_ptr<cricket::VideoMediaInfo> video_media_info,
105 const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders,
106 const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& rtp_receivers)
107 : voice_media_info_(std::move(voice_media_info)),
108 video_media_info_(std::move(video_media_info)) {
hbosfe90ad12017-02-20 02:05:13 -0800109 std::map<uint32_t, AudioTrackInterface*> local_audio_track_by_ssrc;
110 std::map<uint32_t, VideoTrackInterface*> local_video_track_by_ssrc;
111 std::map<uint32_t, AudioTrackInterface*> remote_audio_track_by_ssrc;
112 std::map<uint32_t, VideoTrackInterface*> remote_video_track_by_ssrc;
113 GetAudioAndVideoTrackBySsrc(rtp_senders,
114 rtp_receivers,
115 &local_audio_track_by_ssrc,
116 &local_video_track_by_ssrc,
117 &remote_audio_track_by_ssrc,
118 &remote_video_track_by_ssrc);
hbos1f8239c2017-01-16 04:24:10 -0800119 if (voice_media_info_) {
120 for (auto& sender_info : voice_media_info_->senders) {
121 AudioTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800122 FindValueOrNull(local_audio_track_by_ssrc, sender_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800123 if (associated_track) {
124 // One sender is associated with at most one track.
125 // One track may be associated with multiple senders.
126 audio_track_by_sender_info_[&sender_info] = associated_track;
127 voice_infos_by_local_track_[associated_track].push_back(&sender_info);
128 }
129 }
130 for (auto& receiver_info : voice_media_info_->receivers) {
131 AudioTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800132 FindValueOrNull(remote_audio_track_by_ssrc, receiver_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800133 if (associated_track) {
134 // One receiver is associated with at most one track, which is uniquely
135 // associated with that receiver.
136 audio_track_by_receiver_info_[&receiver_info] = associated_track;
137 RTC_DCHECK(voice_info_by_remote_track_.find(associated_track) ==
138 voice_info_by_remote_track_.end());
139 voice_info_by_remote_track_[associated_track] = &receiver_info;
140 }
141 }
142 }
143 if (video_media_info_) {
144 for (auto& sender_info : video_media_info_->senders) {
145 VideoTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800146 FindValueOrNull(local_video_track_by_ssrc, sender_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800147 if (associated_track) {
148 // One sender is associated with at most one track.
149 // One track may be associated with multiple senders.
150 video_track_by_sender_info_[&sender_info] = associated_track;
151 video_infos_by_local_track_[associated_track].push_back(&sender_info);
152 }
153 }
154 for (auto& receiver_info : video_media_info_->receivers) {
155 VideoTrackInterface* associated_track =
hbosfe90ad12017-02-20 02:05:13 -0800156 FindValueOrNull(remote_video_track_by_ssrc, receiver_info.ssrc());
hbos1f8239c2017-01-16 04:24:10 -0800157 if (associated_track) {
158 // One receiver is associated with at most one track, which is uniquely
159 // associated with that receiver.
160 video_track_by_receiver_info_[&receiver_info] = associated_track;
161 RTC_DCHECK(video_info_by_remote_track_.find(associated_track) ==
162 video_info_by_remote_track_.end());
163 video_info_by_remote_track_[associated_track] = &receiver_info;
164 }
165 }
166 }
167}
168
169const std::vector<cricket::VoiceSenderInfo*>*
170TrackMediaInfoMap::GetVoiceSenderInfos(
171 const AudioTrackInterface& local_audio_track) const {
172 return FindAddressOrNull(voice_infos_by_local_track_, &local_audio_track);
173}
174
175const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfo(
176 const AudioTrackInterface& remote_audio_track) const {
177 return FindValueOrNull(voice_info_by_remote_track_, &remote_audio_track);
178}
179
180const std::vector<cricket::VideoSenderInfo*>*
181TrackMediaInfoMap::GetVideoSenderInfos(
182 const VideoTrackInterface& local_video_track) const {
183 return FindAddressOrNull(video_infos_by_local_track_, &local_video_track);
184}
185
186const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfo(
187 const VideoTrackInterface& remote_video_track) const {
188 return FindValueOrNull(video_info_by_remote_track_, &remote_video_track);
189}
190
191rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack(
192 const cricket::VoiceSenderInfo& voice_sender_info) const {
193 return FindValueOrNull(audio_track_by_sender_info_, &voice_sender_info);
194}
195
196rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack(
197 const cricket::VoiceReceiverInfo& voice_receiver_info) const {
198 return FindValueOrNull(audio_track_by_receiver_info_, &voice_receiver_info);
199}
200
201rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack(
202 const cricket::VideoSenderInfo& video_sender_info) const {
203 return FindValueOrNull(video_track_by_sender_info_, &video_sender_info);
204}
205
206rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack(
207 const cricket::VideoReceiverInfo& video_receiver_info) const {
208 return FindValueOrNull(video_track_by_receiver_info_, &video_receiver_info);
209}
210
211} // namespace webrtc