Chromium Code Reviews| Index: webrtc/api/trackmediainfomap.cc |
| diff --git a/webrtc/api/trackmediainfomap.cc b/webrtc/api/trackmediainfomap.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6ae053b41fad812cc90858644a9e3b187b420849 |
| --- /dev/null |
| +++ b/webrtc/api/trackmediainfomap.cc |
| @@ -0,0 +1,257 @@ |
| +/* |
| + * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| + * |
| + * Use of this source code is governed by a BSD-style license |
| + * that can be found in the LICENSE file in the root of the source |
| + * tree. An additional intellectual property rights grant can be found |
| + * in the file PATENTS. All contributing project authors may |
| + * be found in the AUTHORS file in the root of the source tree. |
| + */ |
| + |
| +#include "webrtc/api/trackmediainfomap.h" |
| + |
| +#include <utility> |
| + |
| +namespace webrtc { |
| + |
| +namespace { |
| + |
| +std::map<uint32_t, MediaStreamTrackInterface*> GetSsrcToTrack( |
|
Taylor Brandstetter
2017/01/05 00:35:42
If not bundling, it's theoretically possible to us
hta-webrtc
2017/01/05 09:46:56
The ID for an SSRC (aka RTPMediaStream) should be
hbos
2017/01/05 15:27:56
I don't see where I get the transport/mid/content
Taylor Brandstetter
2017/01/11 22:12:04
Yes, this is the best you can do now. Currently "m
|
| + const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders, |
| + const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& |
| + rtp_receivers) { |
| + std::map<uint32_t, MediaStreamTrackInterface*> ssrc_to_track; |
| + for (const rtc::scoped_refptr<RtpSenderInterface>& rtp_sender : rtp_senders) { |
| + if (!rtp_sender->track()) { |
| + continue; |
| + } |
| + if (rtp_sender->ssrc() != 0) { |
|
Taylor Brandstetter
2017/01/05 00:35:42
Could add a TODO to remove this once RtpEncodingPa
hbos
2017/01/05 15:27:56
Done.
|
| + RTC_DCHECK(ssrc_to_track.find(rtp_sender->ssrc()) == ssrc_to_track.end()); |
| + ssrc_to_track[rtp_sender->ssrc()] = rtp_sender->track(); |
| + } |
| + RtpParameters params = rtp_sender->GetParameters(); |
| + for (const RtpEncodingParameters& encoding : params.encodings) { |
| + if (!encoding.ssrc || *encoding.ssrc == rtp_sender->ssrc()) { |
| + continue; |
| + } |
| + RTC_DCHECK(ssrc_to_track.find(*encoding.ssrc) == ssrc_to_track.end()); |
| + ssrc_to_track[*encoding.ssrc] = rtp_sender->track(); |
| + } |
| + } |
| + for (const rtc::scoped_refptr<RtpReceiverInterface>& rtp_receiver : |
| + rtp_receivers) { |
| + RTC_DCHECK(rtp_receiver->track()); |
| + RtpParameters params = rtp_receiver->GetParameters(); |
| + for (const RtpEncodingParameters& encoding : params.encodings) { |
| + if (!encoding.ssrc) { |
| + continue; |
| + } |
| + RTC_DCHECK(ssrc_to_track.find(*encoding.ssrc) == ssrc_to_track.end()); |
| + ssrc_to_track[*encoding.ssrc] = rtp_receiver->track(); |
| + } |
| + } |
| + return ssrc_to_track; |
| +} |
| + |
| +template<typename T> |
| +T* CheckedTrackCast(MediaStreamTrackInterface* track); |
| + |
| +template<> |
| +AudioTrackInterface* CheckedTrackCast(MediaStreamTrackInterface* track) { |
| + RTC_DCHECK_EQ(track->kind(), MediaStreamTrackInterface::kAudioKind); |
| + return static_cast<AudioTrackInterface*>(track); |
| +} |
| + |
| +template<> |
| +VideoTrackInterface* CheckedTrackCast(MediaStreamTrackInterface* track) { |
| + RTC_DCHECK_EQ(track->kind(), MediaStreamTrackInterface::kVideoKind); |
| + return static_cast<VideoTrackInterface*>(track); |
| +} |
| + |
| +// Template in order to support both the audio and video case. |
| +template<typename TrackType, typename InfoType> |
| +TrackType* GetAssociatedTrack( |
| + const std::map<uint32_t, MediaStreamTrackInterface*>& ssrc_to_track, |
| + const InfoType& info) { |
| + std::map<uint32_t, MediaStreamTrackInterface*>::const_iterator it = |
| + ssrc_to_track.find(info.ssrc()); |
| + if (it == ssrc_to_track.end()) { |
| + return nullptr; |
| + } |
| + return CheckedTrackCast<TrackType>(it->second); |
| +} |
| + |
| +// Template in order to support both the audio and video case. |
| +template<typename TrackType, |
| + typename MediaInfoType, |
| + typename SenderInfoToTrackType, |
| + typename LocalTrackToInfosType, |
| + typename ReceiverInfoToTrackType, |
| + typename RemoteTrackToInfosType> |
| +void MapTracksAndInfos( |
| + const std::map<uint32_t, MediaStreamTrackInterface*>& ssrc_to_track, |
| + MediaInfoType* media_info, |
| + SenderInfoToTrackType* sender_info_to_track, |
| + LocalTrackToInfosType* local_track_to_infos, |
| + ReceiverInfoToTrackType* receiver_info_to_track, |
| + RemoteTrackToInfosType* remote_track_to_info) { |
| + for (auto& sender_info : media_info->senders) { |
| + TrackType* associated_track = GetAssociatedTrack<TrackType>( |
| + ssrc_to_track, sender_info); |
| + if (associated_track) { |
| + // One sender is associated with at most one track. |
| + // One track may be associated with multiple senders. |
| + (*sender_info_to_track)[&sender_info] = associated_track; |
| + (*local_track_to_infos)[associated_track].push_back(&sender_info); |
| + } |
| + } |
| + for (auto& receiver_info : media_info->receivers) { |
| + TrackType* associated_track = GetAssociatedTrack<TrackType>( |
| + ssrc_to_track, receiver_info); |
| + if (associated_track) { |
| + // One receiver is associated with at most one track, which is uniquely |
| + // associated with that receiver. |
| + (*receiver_info_to_track)[&receiver_info] = associated_track; |
| + RTC_DCHECK(remote_track_to_info->find(associated_track) == |
| + remote_track_to_info->end()); |
| + (*remote_track_to_info)[associated_track] = &receiver_info; |
| + } |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +TrackMediaInfoMap::TrackMediaInfoMap( |
| + std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info, |
| + std::unique_ptr<cricket::VideoMediaInfo> video_media_info) |
| + : is_initialized_(false), |
| + voice_media_info_(std::move(voice_media_info)), |
| + video_media_info_(std::move(video_media_info)) { |
| +} |
| + |
| +void TrackMediaInfoMap::Initialize( |
| + const std::vector<rtc::scoped_refptr<RtpSenderInterface>>& rtp_senders, |
| + const std::vector<rtc::scoped_refptr<RtpReceiverInterface>>& |
| + rtp_receivers) { |
| + RTC_DCHECK(!is_initialized_); |
| + is_initialized_ = true; |
|
hta-webrtc
2017/01/05 09:46:56
Here's the part that is not thread-safe (but it ma
hbos
2017/01/05 15:27:56
Merged Initialize with constructor.
|
| + std::map<uint32_t, MediaStreamTrackInterface*> ssrc_to_track = |
| + GetSsrcToTrack(rtp_senders, rtp_receivers); |
| + |
| + if (voice_media_info_) { |
| + MapTracksAndInfos<AudioTrackInterface>(ssrc_to_track, |
| + voice_media_info_.get(), |
| + &voice_sender_info_to_track_, |
| + &local_audio_track_to_infos_, |
| + &voice_receiver_info_to_track_, |
| + &remote_audio_track_to_info_); |
| + } |
| + if (video_media_info_) { |
| + MapTracksAndInfos<VideoTrackInterface>(ssrc_to_track, |
| + video_media_info_.get(), |
| + &video_sender_info_to_track_, |
| + &local_video_track_to_infos_, |
| + &video_receiver_info_to_track_, |
| + &remote_video_track_to_info_); |
| + } |
| +} |
| + |
| +const std::vector<cricket::VoiceSenderInfo*>* |
| +TrackMediaInfoMap::GetVoiceSenderInfos( |
| + const AudioTrackInterface& local_audio_track) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const AudioTrackInterface*, |
| + std::vector<cricket::VoiceSenderInfo*>>::const_iterator it = |
| + local_audio_track_to_infos_.find(&local_audio_track); |
| + if (it == local_audio_track_to_infos_.end()) { |
| + return nullptr; |
| + } |
| + return &it->second; |
| +} |
| + |
| +const cricket::VoiceReceiverInfo* TrackMediaInfoMap::GetVoiceReceiverInfo( |
| + const AudioTrackInterface& remote_audio_track) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const AudioTrackInterface*, |
| + cricket::VoiceReceiverInfo*>::const_iterator it = |
| + remote_audio_track_to_info_.find(&remote_audio_track); |
| + if (it == remote_audio_track_to_info_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +const std::vector<cricket::VideoSenderInfo*>* |
| +TrackMediaInfoMap::GetVideoSenderInfos( |
| + const VideoTrackInterface& local_video_track) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const VideoTrackInterface*, |
| + std::vector<cricket::VideoSenderInfo*>>::const_iterator it = |
| + local_video_track_to_infos_.find(&local_video_track); |
| + if (it == local_video_track_to_infos_.end()) { |
| + return nullptr; |
| + } |
| + return &it->second; |
| +} |
| + |
| +const cricket::VideoReceiverInfo* TrackMediaInfoMap::GetVideoReceiverInfo( |
| + const VideoTrackInterface& remote_video_track) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const VideoTrackInterface*, |
| + cricket::VideoReceiverInfo*>::const_iterator it = |
| + remote_video_track_to_info_.find(&remote_video_track); |
| + if (it == remote_video_track_to_info_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack( |
| + const cricket::VoiceSenderInfo& voice_sender_info) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const cricket::VoiceSenderInfo*, |
| + rtc::scoped_refptr<AudioTrackInterface>>::const_iterator it = |
| + voice_sender_info_to_track_.find(&voice_sender_info); |
| + if (it == voice_sender_info_to_track_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +rtc::scoped_refptr<AudioTrackInterface> TrackMediaInfoMap::GetAudioTrack( |
| + const cricket::VoiceReceiverInfo& voice_receiver_info) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const cricket::VoiceReceiverInfo*, |
| + rtc::scoped_refptr<AudioTrackInterface>>::const_iterator it = |
| + voice_receiver_info_to_track_.find(&voice_receiver_info); |
| + if (it == voice_receiver_info_to_track_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack( |
| + const cricket::VideoSenderInfo& video_sender_info) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const cricket::VideoSenderInfo*, |
| + rtc::scoped_refptr<VideoTrackInterface>>::const_iterator it = |
| + video_sender_info_to_track_.find(&video_sender_info); |
| + if (it == video_sender_info_to_track_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +rtc::scoped_refptr<VideoTrackInterface> TrackMediaInfoMap::GetVideoTrack( |
| + const cricket::VideoReceiverInfo& video_receiver_info) const { |
| + RTC_DCHECK(is_initialized_); |
| + std::map<const cricket::VideoReceiverInfo*, |
| + rtc::scoped_refptr<VideoTrackInterface>>::const_iterator it = |
| + video_receiver_info_to_track_.find(&video_receiver_info); |
| + if (it == video_receiver_info_to_track_.end()) { |
| + return nullptr; |
| + } |
| + return it->second; |
| +} |
| + |
| +} // namespace webrtc |