1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/remote_media_stream_impl.h" 6 7 #include <string> 8 9 #include "base/logging.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "content/renderer/media/media_stream_dependency_factory.h" 12 #include "content/renderer/media/media_stream_extra_data.h" 13 #include "third_party/WebKit/public/platform/WebString.h" 14 15 namespace content { 16 17 // RemoteMediaStreamTrackObserver is responsible for listening on change 18 // notification on a remote webrtc MediaStreamTrack and notify WebKit. 19 class RemoteMediaStreamTrackObserver 20 : NON_EXPORTED_BASE(public webrtc::ObserverInterface), 21 NON_EXPORTED_BASE(public base::NonThreadSafe) { 22 public: 23 RemoteMediaStreamTrackObserver( 24 webrtc::MediaStreamTrackInterface* webrtc_track, 25 const blink::WebMediaStreamTrack& webkit_track); 26 virtual ~RemoteMediaStreamTrackObserver(); 27 28 webrtc::MediaStreamTrackInterface* observered_track() { 29 return webrtc_track_.get(); 30 } 31 const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; } 32 33 private: 34 // webrtc::ObserverInterface implementation. 35 virtual void OnChanged() OVERRIDE; 36 37 webrtc::MediaStreamTrackInterface::TrackState state_; 38 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_; 39 blink::WebMediaStreamTrack webkit_track_; 40 41 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackObserver); 42 }; 43 44 } // namespace content 45 46 namespace { 47 48 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track, 49 blink::WebMediaStreamTrack* webkit_track, 50 blink::WebMediaStreamSource::Type type) { 51 blink::WebMediaStreamSource webkit_source; 52 blink::WebString webkit_track_id(UTF8ToUTF16(track->id())); 53 54 webkit_source.initialize(webkit_track_id, type, webkit_track_id); 55 webkit_track->initialize(webkit_track_id, webkit_source); 56 content::MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack( 57 track, *webkit_track, false); 58 } 59 60 content::RemoteMediaStreamTrackObserver* FindTrackObserver( 61 webrtc::MediaStreamTrackInterface* track, 62 const ScopedVector<content::RemoteMediaStreamTrackObserver>& observers) { 63 ScopedVector<content::RemoteMediaStreamTrackObserver>::const_iterator it = 64 observers.begin(); 65 for (; it != observers.end(); ++it) { 66 if ((*it)->observered_track() == track) 67 return *it; 68 } 69 return NULL; 70 } 71 72 } // namespace anonymous 73 74 namespace content { 75 76 RemoteMediaStreamTrackObserver::RemoteMediaStreamTrackObserver( 77 webrtc::MediaStreamTrackInterface* webrtc_track, 78 const blink::WebMediaStreamTrack& webkit_track) 79 : state_(webrtc_track->state()), 80 webrtc_track_(webrtc_track), 81 webkit_track_(webkit_track) { 82 webrtc_track->RegisterObserver(this); 83 } 84 85 RemoteMediaStreamTrackObserver::~RemoteMediaStreamTrackObserver() { 86 webrtc_track_->UnregisterObserver(this); 87 } 88 89 void RemoteMediaStreamTrackObserver::OnChanged() { 90 DCHECK(CalledOnValidThread()); 91 92 webrtc::MediaStreamTrackInterface::TrackState state = webrtc_track_->state(); 93 if (state == state_) 94 return; 95 96 state_ = state; 97 switch (state) { 98 case webrtc::MediaStreamTrackInterface::kInitializing: 99 // Ignore the kInitializing state since there is no match in 100 // WebMediaStreamSource::ReadyState. 101 break; 102 case webrtc::MediaStreamTrackInterface::kLive: 103 webkit_track_.source().setReadyState( 104 blink::WebMediaStreamSource::ReadyStateLive); 105 break; 106 case webrtc::MediaStreamTrackInterface::kEnded: 107 webkit_track_.source().setReadyState( 108 blink::WebMediaStreamSource::ReadyStateEnded); 109 break; 110 default: 111 NOTREACHED(); 112 break; 113 } 114 } 115 116 RemoteMediaStreamImpl::RemoteMediaStreamImpl( 117 webrtc::MediaStreamInterface* webrtc_stream) 118 : webrtc_stream_(webrtc_stream) { 119 webrtc_stream_->RegisterObserver(this); 120 121 webrtc::AudioTrackVector webrtc_audio_tracks = 122 webrtc_stream_->GetAudioTracks(); 123 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( 124 webrtc_audio_tracks.size()); 125 126 // Initialize WebKit audio tracks. 127 size_t i = 0; 128 for (; i < webrtc_audio_tracks.size(); ++i) { 129 webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i]; 130 DCHECK(audio_track); 131 InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i], 132 blink::WebMediaStreamSource::TypeAudio); 133 audio_track_observers_.push_back( 134 new RemoteMediaStreamTrackObserver(audio_track, 135 webkit_audio_tracks[i])); 136 } 137 138 // Initialize WebKit video tracks. 139 webrtc::VideoTrackVector webrtc_video_tracks = 140 webrtc_stream_->GetVideoTracks(); 141 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( 142 webrtc_video_tracks.size()); 143 for (i = 0; i < webrtc_video_tracks.size(); ++i) { 144 webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i]; 145 DCHECK(video_track); 146 InitializeWebkitTrack(video_track, &webkit_video_tracks[i], 147 blink::WebMediaStreamSource::TypeVideo); 148 video_track_observers_.push_back( 149 new RemoteMediaStreamTrackObserver(video_track, 150 webkit_video_tracks[i])); 151 } 152 153 webkit_stream_.initialize(UTF8ToUTF16(webrtc_stream->label()), 154 webkit_audio_tracks, webkit_video_tracks); 155 webkit_stream_.setExtraData(new MediaStreamExtraData(webrtc_stream, false)); 156 } 157 158 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { 159 webrtc_stream_->UnregisterObserver(this); 160 } 161 162 void RemoteMediaStreamImpl::OnChanged() { 163 // Find removed audio tracks. 164 ScopedVector<RemoteMediaStreamTrackObserver>::iterator audio_it = 165 audio_track_observers_.begin(); 166 while (audio_it != audio_track_observers_.end()) { 167 std::string track_id = (*audio_it)->observered_track()->id(); 168 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { 169 webkit_stream_.removeTrack((*audio_it)->webkit_track()); 170 audio_it = audio_track_observers_.erase(audio_it); 171 } else { 172 ++audio_it; 173 } 174 } 175 176 // Find removed video tracks. 177 ScopedVector<RemoteMediaStreamTrackObserver>::iterator video_it = 178 video_track_observers_.begin(); 179 while (video_it != video_track_observers_.end()) { 180 std::string track_id = (*video_it)->observered_track()->id(); 181 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { 182 webkit_stream_.removeTrack((*video_it)->webkit_track()); 183 video_it = video_track_observers_.erase(video_it); 184 } else { 185 ++video_it; 186 } 187 } 188 189 // Find added audio tracks. 190 webrtc::AudioTrackVector webrtc_audio_tracks = 191 webrtc_stream_->GetAudioTracks(); 192 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); 193 it != webrtc_audio_tracks.end(); ++it) { 194 if (!FindTrackObserver(*it, audio_track_observers_)) { 195 blink::WebMediaStreamTrack new_track; 196 InitializeWebkitTrack(*it, &new_track, 197 blink::WebMediaStreamSource::TypeAudio); 198 audio_track_observers_.push_back( 199 new RemoteMediaStreamTrackObserver(*it, new_track)); 200 webkit_stream_.addTrack(new_track); 201 } 202 } 203 204 // Find added video tracks. 205 webrtc::VideoTrackVector webrtc_video_tracks = 206 webrtc_stream_->GetVideoTracks(); 207 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); 208 it != webrtc_video_tracks.end(); ++it) { 209 if (!FindTrackObserver(*it, video_track_observers_)) { 210 blink::WebMediaStreamTrack new_track; 211 InitializeWebkitTrack(*it, &new_track, 212 blink::WebMediaStreamSource::TypeVideo); 213 video_track_observers_.push_back( 214 new RemoteMediaStreamTrackObserver(*it, new_track)); 215 webkit_stream_.addTrack(new_track); 216 } 217 } 218 } 219 220 } // namespace content 221