Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/remote_media_stream_impl.h" | 5 #include "content/renderer/media/remote_media_stream_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | |
| 10 #include "base/location.h" | |
| 9 #include "base/logging.h" | 11 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/thread_task_runner_handle.h" | |
| 11 #include "content/renderer/media/media_stream.h" | 14 #include "content/renderer/media/media_stream.h" |
| 15 #include "content/renderer/media/media_stream_track.h" | |
| 12 #include "content/renderer/media/media_stream_video_track.h" | 16 #include "content/renderer/media/media_stream_video_track.h" |
| 13 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" | 17 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" |
| 14 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | 18 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
| 15 #include "third_party/WebKit/public/platform/WebString.h" | 19 #include "third_party/WebKit/public/platform/WebString.h" |
| 16 | 20 |
| 17 namespace content { | 21 namespace content { |
| 18 | |
| 19 namespace { | 22 namespace { |
| 20 | 23 |
| 21 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track, | 24 template <typename WebRtcTrackVector, typename AdapterType> |
| 22 blink::WebMediaStreamTrack* webkit_track, | 25 void CreateAdaptersForTracks( |
| 23 blink::WebMediaStreamSource::Type type) { | 26 const WebRtcTrackVector& tracks, |
| 24 blink::WebMediaStreamSource webkit_source; | 27 std::vector<scoped_refptr<AdapterType>>* observers, |
| 25 blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id())); | 28 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { |
| 26 | 29 for (auto& track : tracks) |
| 27 webkit_source.initialize(webkit_track_id, type, webkit_track_id); | 30 observers->push_back(new AdapterType(main_thread, track)); |
| 28 webkit_track->initialize(webkit_track_id, webkit_source); | 31 } |
| 29 | 32 |
| 30 if (type == blink::WebMediaStreamSource::TypeVideo) { | 33 template<typename VectorType> |
| 31 MediaStreamRemoteVideoSource* video_source = | 34 bool IsTrackInVector(const VectorType& v, const std::string& id) { |
| 32 new MediaStreamRemoteVideoSource( | 35 for (const auto& t : v) { |
| 33 static_cast<webrtc::VideoTrackInterface*>(track)); | 36 if (t->id() == id) |
| 34 webkit_source.setExtraData(video_source); | 37 return true; |
| 38 } | |
| 39 return false; | |
| 40 } | |
| 41 } // namespace | |
| 42 | |
| 43 // TODO(tommi): Move this class to a separate set of files. | |
| 44 class RemoteMediaStreamAudioTrack : public MediaStreamTrack { | |
| 45 public: | |
| 46 RemoteMediaStreamAudioTrack( | |
| 47 const scoped_refptr<webrtc::MediaStreamTrackInterface>& track, | |
|
perkj_chrome
2014/10/31 08:37:25
This can be webrtc::AudioTrackInterface instead of
tommi (sloooow) - chröme
2014/10/31 10:06:32
Done.
| |
| 48 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) | |
| 49 : MediaStreamTrack(false), track_(track), | |
| 50 signaling_thread_(signaling_thread) { | |
| 51 } | |
| 52 | |
| 53 ~RemoteMediaStreamAudioTrack() override {} | |
| 54 | |
| 55 private: | |
| 56 void SetEnabled(bool enabled) override { | |
| 57 if (!track_.get()) | |
| 58 return; | |
| 59 | |
| 60 // Due to a discrepancy in libjingle, we have to post to the signaling | |
| 61 // thread. Usually we get a proxy object, but in the case of audio tracks, | |
| 62 // we get a direct pointer to the object. | |
|
perkj_chrome
2014/10/31 08:37:24
I don't think this is true for remote audio tracks
tommi (sloooow) - chröme
2014/10/31 10:06:32
Yes, you're right. The code is bit by bit becoming
| |
| 63 signaling_thread_->PostTask(FROM_HERE, base::Bind( | |
| 64 base::IgnoreResult(&webrtc::MediaStreamTrackInterface::set_enabled), | |
| 65 track_, enabled)); | |
| 66 } | |
| 67 | |
| 68 void Stop() override { | |
| 69 // Stop means that a track should be stopped permanently. But | |
| 70 // since there is no proper way of doing that on a remote track, we can | |
| 71 // at least disable the track. Blink will not call down to the content layer | |
| 72 // after a track has been stopped. | |
| 73 SetEnabled(false); | |
| 74 } | |
| 75 | |
| 76 webrtc::AudioTrackInterface* GetAudioAdapter() override { | |
|
perkj_chrome
2014/10/31 08:37:24
This method is really weird.
I see its being used
tommi (sloooow) - chröme
2014/10/31 10:06:33
Yes, DTMFSender only works for local audio tracks.
perkj_chrome
2014/10/31 10:24:26
My point is, if this should never be used on remot
tommi (sloooow) - chröme
2014/10/31 13:20:41
Yes, you're right (and reading my comment I guess
| |
| 77 // Since the object pointed to by |track_| is not a proxy object but | |
| 78 // actually a pointer to a single threaded object that lives on the | |
| 79 // signaling thread, we need to make sure we're on the right thread. | |
| 80 // However, today (Oct 2014), I'm not aware of any callers to this method | |
| 81 // for remote audio tracks. | |
| 82 DCHECK(signaling_thread_->BelongsToCurrentThread()); | |
| 83 DCHECK_EQ(track_->kind(), "audio"); | |
| 84 return static_cast<webrtc::AudioTrackInterface*>(track_.get()); | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 const scoped_refptr<webrtc::MediaStreamTrackInterface> track_; | |
| 89 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; | |
| 90 }; | |
| 91 | |
| 92 // Base class used for mapping between webrtc and blink MediaStream tracks. | |
| 93 // An instance of a RemoteMediaStreamAudioTrackAdapter is stored in | |
| 94 // RemoteMediaStreamImpl per remote audio and video track. | |
| 95 template<typename WebRtcMediaStreamTrackType> | |
| 96 class RemoteMediaStreamAudioTrackAdapter | |
|
perkj_chrome
2014/10/31 08:37:25
This looks like a search and replace error. You di
tommi (sloooow) - chröme
2014/10/31 10:06:33
Doh, thanks.
| |
| 97 : public base::RefCountedThreadSafe< | |
| 98 RemoteMediaStreamAudioTrackAdapter<WebRtcMediaStreamTrackType>> { | |
| 99 public: | |
| 100 RemoteMediaStreamAudioTrackAdapter( | |
| 101 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 102 WebRtcMediaStreamTrackType* webrtc_track) | |
| 103 : main_thread_(main_thread), webrtc_track_(webrtc_track), | |
| 104 id_(webrtc_track->id()) { | |
| 105 } | |
| 106 | |
| 107 const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() { | |
| 108 return webrtc_track_; | |
| 109 } | |
| 110 | |
| 111 blink::WebMediaStreamTrack* webkit_track() { | |
| 112 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 113 DCHECK(!webkit_track_.isNull()); | |
| 114 return &webkit_track_; | |
| 115 } | |
| 116 | |
| 117 const std::string& id() const { return id_; } | |
| 118 | |
| 119 bool initialized() const { | |
| 120 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 121 return !webkit_track_.isNull(); | |
| 122 } | |
| 123 | |
| 124 void Initialize() { | |
| 125 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 126 DCHECK(!initialized()); | |
| 127 webkit_initialize_.Run(); | |
| 128 webkit_initialize_.Reset(); | |
| 129 DCHECK(initialized()); | |
| 130 } | |
| 131 | |
| 132 protected: | |
| 133 friend class base::RefCountedThreadSafe< | |
| 134 RemoteMediaStreamAudioTrackAdapter<WebRtcMediaStreamTrackType>>; | |
| 135 | |
| 136 virtual ~RemoteMediaStreamAudioTrackAdapter() { | |
| 137 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 138 } | |
| 139 | |
| 140 void InitializeWebkitTrack(blink::WebMediaStreamSource::Type type) { | |
| 141 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 142 DCHECK(webkit_track_.isNull()); | |
| 143 | |
| 144 blink::WebString webkit_track_id(base::UTF8ToUTF16(id_)); | |
| 145 blink::WebMediaStreamSource webkit_source; | |
| 146 webkit_source.initialize(webkit_track_id, type, webkit_track_id); | |
| 147 webkit_track_.initialize(webkit_track_id, webkit_source); | |
| 148 DCHECK(!webkit_track_.isNull()); | |
| 149 } | |
| 150 | |
| 151 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; | |
| 152 // This callback will be run when Initialize() is called and then freed. | |
| 153 // The callback is used by derived classes to bind objects that need to be | |
| 154 // instantiated and initialized on the signaling thread but then moved to | |
| 155 // and used on the main thread when initializing the webkit object(s). | |
| 156 base::Callback<void()> webkit_initialize_; | |
| 157 | |
| 158 private: | |
| 159 const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_; | |
| 160 blink::WebMediaStreamTrack webkit_track_; | |
| 161 // const copy of the webrtc track id that allows us to check it from both the | |
| 162 // main and signaling threads without incurring a synchronous thread hop. | |
| 163 const std::string id_; | |
| 164 | |
| 165 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamAudioTrackAdapter); | |
| 166 }; | |
| 167 | |
| 168 class RemoteVideoTrackAdapter | |
| 169 : public RemoteMediaStreamAudioTrackAdapter<webrtc::VideoTrackInterface> { | |
|
perkj_chrome
2014/10/31 08:37:24
Weird name of baseclass...
tommi (sloooow) - chröme
2014/10/31 10:06:33
Acknowledged.
| |
| 170 public: | |
| 171 // Called on the signaling thread | |
| 172 RemoteVideoTrackAdapter( | |
| 173 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 174 webrtc::VideoTrackInterface* webrtc_track) | |
| 175 : RemoteMediaStreamAudioTrackAdapter(main_thread, webrtc_track) { | |
| 176 scoped_refptr<MediaStreamRemoteVideoSource::Observer> source_observer( | |
| 177 new MediaStreamRemoteVideoSource::Observer(main_thread, | |
| 178 observed_track().get())); | |
| 179 webkit_initialize_ = base::Bind( | |
| 180 &RemoteVideoTrackAdapter::InitializeWebkitVideoTrack, | |
| 181 this, source_observer, observed_track()->enabled()); | |
| 182 } | |
| 183 | |
| 184 protected: | |
| 185 ~RemoteVideoTrackAdapter() override {} | |
| 186 | |
| 187 private: | |
| 188 void InitializeWebkitVideoTrack( | |
| 189 const scoped_refptr<MediaStreamRemoteVideoSource::Observer>& observer, | |
| 190 bool enabled) { | |
| 191 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 192 scoped_ptr<MediaStreamRemoteVideoSource> video_source( | |
| 193 new MediaStreamRemoteVideoSource(observer)); | |
| 194 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeVideo); | |
| 195 webkit_track()->source().setExtraData(video_source.get()); | |
| 35 // Initial constraints must be provided to a MediaStreamVideoTrack. But | 196 // Initial constraints must be provided to a MediaStreamVideoTrack. But |
| 36 // no constraints are available initially on a remote video track. | 197 // no constraints are available initially on a remote video track. |
| 37 blink::WebMediaConstraints constraints; | 198 blink::WebMediaConstraints constraints; |
| 38 constraints.initialize(); | 199 constraints.initialize(); |
| 39 webkit_track->setExtraData( | 200 MediaStreamVideoTrack* media_stream_track = |
| 40 new MediaStreamVideoTrack(video_source, constraints, | 201 new MediaStreamVideoTrack(video_source.release(), constraints, |
| 41 MediaStreamVideoSource::ConstraintsCallback(), | 202 MediaStreamVideoSource::ConstraintsCallback(), enabled); |
| 42 track->enabled())); | 203 webkit_track()->setExtraData(media_stream_track); |
| 43 } else { | 204 } |
| 44 DCHECK(type == blink::WebMediaStreamSource::TypeAudio); | 205 }; |
| 45 content::PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack( | 206 |
| 46 track, *webkit_track, false); | 207 // RemoteAudioTrackAdapter is responsible for listening on state |
| 47 } | |
| 48 } | |
| 49 | |
| 50 } // namespace | |
| 51 | |
| 52 // Base class used for mapping between webrtc and blink MediaStream tracks. | |
| 53 // An instance of a RemoteMediaStreamTrackAdapter is stored in | |
| 54 // RemoteMediaStreamImpl per remote audio and video track. | |
| 55 class RemoteMediaStreamTrackAdapter { | |
| 56 public: | |
| 57 RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track, | |
| 58 const blink::WebMediaStreamTrack& webkit_track) | |
| 59 : webrtc_track_(webrtc_track), | |
| 60 webkit_track_(webkit_track) { | |
| 61 } | |
| 62 | |
| 63 virtual ~RemoteMediaStreamTrackAdapter() { | |
| 64 } | |
| 65 | |
| 66 webrtc::MediaStreamTrackInterface* observed_track() { | |
| 67 return webrtc_track_.get(); | |
| 68 } | |
| 69 | |
| 70 const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; } | |
| 71 | |
| 72 private: | |
| 73 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_; | |
| 74 blink::WebMediaStreamTrack webkit_track_; | |
| 75 | |
| 76 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); | |
| 77 }; | |
| 78 | |
| 79 static content::RemoteMediaStreamTrackAdapter* FindTrackObserver( | |
| 80 webrtc::MediaStreamTrackInterface* track, | |
| 81 const ScopedVector<content::RemoteMediaStreamTrackAdapter>& observers) { | |
| 82 ScopedVector<content::RemoteMediaStreamTrackAdapter>::const_iterator it = | |
| 83 observers.begin(); | |
| 84 for (; it != observers.end(); ++it) { | |
| 85 if ((*it)->observed_track() == track) | |
| 86 return *it; | |
| 87 } | |
| 88 return NULL; | |
| 89 } | |
| 90 | |
| 91 // RemoteAudioMediaStreamTrackAdapter is responsible for listening on state | |
| 92 // change notifications on a remote webrtc audio MediaStreamTracks and notify | 208 // change notifications on a remote webrtc audio MediaStreamTracks and notify |
| 93 // WebKit. | 209 // WebKit. |
| 94 class RemoteAudioMediaStreamTrackAdapter | 210 class RemoteAudioTrackAdapter |
| 95 : public RemoteMediaStreamTrackAdapter, | 211 : public RemoteMediaStreamAudioTrackAdapter<webrtc::AudioTrackInterface>, |
| 96 public webrtc::ObserverInterface, | 212 public webrtc::ObserverInterface { |
| 97 public base::NonThreadSafe { | 213 public: |
| 98 public: | 214 RemoteAudioTrackAdapter( |
| 99 RemoteAudioMediaStreamTrackAdapter( | 215 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 100 webrtc::MediaStreamTrackInterface* webrtc_track, | 216 webrtc::AudioTrackInterface* webrtc_track); |
| 101 const blink::WebMediaStreamTrack& webkit_track); | 217 |
| 102 ~RemoteAudioMediaStreamTrackAdapter() override; | 218 protected: |
| 103 | 219 ~RemoteAudioTrackAdapter() override; |
| 104 private: | 220 |
| 221 private: | |
| 222 void InitializeWebkitAudioTrack( | |
| 223 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track); | |
| 224 | |
| 105 // webrtc::ObserverInterface implementation. | 225 // webrtc::ObserverInterface implementation. |
| 106 void OnChanged() override; | 226 void OnChanged() override; |
| 107 | 227 |
| 228 void OnChangedOnMainThread( | |
| 229 webrtc::MediaStreamTrackInterface::TrackState state); | |
| 230 | |
| 108 webrtc::MediaStreamTrackInterface::TrackState state_; | 231 webrtc::MediaStreamTrackInterface::TrackState state_; |
| 109 | 232 |
| 110 DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter); | 233 DISALLOW_COPY_AND_ASSIGN(RemoteAudioTrackAdapter); |
| 111 }; | 234 }; |
| 112 | 235 |
| 113 RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter( | 236 // Called on the signaling thread. |
| 114 webrtc::MediaStreamTrackInterface* webrtc_track, | 237 RemoteAudioTrackAdapter::RemoteAudioTrackAdapter( |
| 115 const blink::WebMediaStreamTrack& webkit_track) | 238 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 116 : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track), | 239 webrtc::AudioTrackInterface* webrtc_track) |
| 240 : RemoteMediaStreamAudioTrackAdapter(main_thread, webrtc_track), | |
| 117 state_(observed_track()->state()) { | 241 state_(observed_track()->state()) { |
| 118 observed_track()->RegisterObserver(this); | 242 observed_track()->RegisterObserver(this); |
| 119 } | 243 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track( |
| 120 | 244 new RemoteMediaStreamAudioTrack(observed_track().get(), |
| 121 RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() { | 245 base::ThreadTaskRunnerHandle::Get())); |
| 246 webkit_initialize_ = base::Bind( | |
| 247 &RemoteAudioTrackAdapter::InitializeWebkitAudioTrack, | |
| 248 this, base::Passed(&media_stream_track)); | |
| 249 } | |
| 250 | |
| 251 RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() { | |
| 122 observed_track()->UnregisterObserver(this); | 252 observed_track()->UnregisterObserver(this); |
| 123 } | 253 } |
| 124 | 254 |
| 125 void RemoteAudioMediaStreamTrackAdapter::OnChanged() { | 255 void RemoteAudioTrackAdapter::InitializeWebkitAudioTrack( |
| 126 DCHECK(CalledOnValidThread()); | 256 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track) { |
| 127 | 257 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeAudio); |
| 128 webrtc::MediaStreamTrackInterface::TrackState state = | 258 webkit_track()->setExtraData(media_stream_track.release()); |
| 129 observed_track()->state(); | 259 } |
| 130 if (state == state_) | 260 |
| 261 void RemoteAudioTrackAdapter::OnChanged() { | |
| 262 main_thread_->PostTask(FROM_HERE, | |
| 263 base::Bind(&RemoteAudioTrackAdapter::OnChangedOnMainThread, | |
| 264 this, observed_track()->state())); | |
| 265 } | |
| 266 | |
| 267 void RemoteAudioTrackAdapter::OnChangedOnMainThread( | |
| 268 webrtc::MediaStreamTrackInterface::TrackState state) { | |
| 269 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 270 | |
| 271 if (state == state_ || !initialized()) | |
| 131 return; | 272 return; |
| 132 | 273 |
| 133 state_ = state; | 274 state_ = state; |
| 275 | |
| 134 switch (state) { | 276 switch (state) { |
| 135 case webrtc::MediaStreamTrackInterface::kInitializing: | 277 case webrtc::MediaStreamTrackInterface::kInitializing: |
| 136 // Ignore the kInitializing state since there is no match in | 278 // Ignore the kInitializing state since there is no match in |
| 137 // WebMediaStreamSource::ReadyState. | 279 // WebMediaStreamSource::ReadyState. |
| 138 break; | 280 break; |
| 139 case webrtc::MediaStreamTrackInterface::kLive: | 281 case webrtc::MediaStreamTrackInterface::kLive: |
| 140 webkit_track().source().setReadyState( | 282 webkit_track()->source().setReadyState( |
| 141 blink::WebMediaStreamSource::ReadyStateLive); | 283 blink::WebMediaStreamSource::ReadyStateLive); |
| 142 break; | 284 break; |
| 143 case webrtc::MediaStreamTrackInterface::kEnded: | 285 case webrtc::MediaStreamTrackInterface::kEnded: |
| 144 webkit_track().source().setReadyState( | 286 webkit_track()->source().setReadyState( |
| 145 blink::WebMediaStreamSource::ReadyStateEnded); | 287 blink::WebMediaStreamSource::ReadyStateEnded); |
| 146 break; | 288 break; |
| 147 default: | 289 default: |
| 148 NOTREACHED(); | 290 NOTREACHED(); |
| 149 break; | 291 break; |
| 150 } | 292 } |
| 151 } | 293 } |
| 152 | 294 |
| 295 // Called on the signaling thread. | |
| 153 RemoteMediaStreamImpl::RemoteMediaStreamImpl( | 296 RemoteMediaStreamImpl::RemoteMediaStreamImpl( |
| 297 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 154 webrtc::MediaStreamInterface* webrtc_stream) | 298 webrtc::MediaStreamInterface* webrtc_stream) |
| 155 : webrtc_stream_(webrtc_stream) { | 299 : main_thread_(main_thread), |
| 300 signaling_thread_(base::ThreadTaskRunnerHandle::Get()), | |
| 301 webrtc_stream_(webrtc_stream) { | |
| 156 webrtc_stream_->RegisterObserver(this); | 302 webrtc_stream_->RegisterObserver(this); |
| 157 | 303 |
| 158 webrtc::AudioTrackVector webrtc_audio_tracks = | 304 CreateAdaptersForTracks(webrtc_stream_->GetAudioTracks(), |
| 159 webrtc_stream_->GetAudioTracks(); | 305 &audio_track_observers_, main_thread); |
| 160 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( | 306 CreateAdaptersForTracks(webrtc_stream_->GetVideoTracks(), |
| 161 webrtc_audio_tracks.size()); | 307 &video_track_observers_, main_thread); |
| 162 | 308 |
| 163 // Initialize WebKit audio tracks. | 309 main_thread_->PostTask(FROM_HERE, |
| 164 size_t i = 0; | 310 base::Bind(&RemoteMediaStreamImpl::InitializeOnMainThread, |
| 165 for (; i < webrtc_audio_tracks.size(); ++i) { | 311 base::Unretained(this), webrtc_stream_->label())); |
| 166 webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i]; | |
| 167 DCHECK(audio_track); | |
| 168 InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i], | |
| 169 blink::WebMediaStreamSource::TypeAudio); | |
| 170 audio_track_observers_.push_back( | |
| 171 new RemoteAudioMediaStreamTrackAdapter(audio_track, | |
| 172 webkit_audio_tracks[i])); | |
| 173 } | |
| 174 | |
| 175 // Initialize WebKit video tracks. | |
| 176 webrtc::VideoTrackVector webrtc_video_tracks = | |
| 177 webrtc_stream_->GetVideoTracks(); | |
| 178 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( | |
| 179 webrtc_video_tracks.size()); | |
| 180 for (i = 0; i < webrtc_video_tracks.size(); ++i) { | |
| 181 webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i]; | |
| 182 DCHECK(video_track); | |
| 183 InitializeWebkitTrack(video_track, &webkit_video_tracks[i], | |
| 184 blink::WebMediaStreamSource::TypeVideo); | |
| 185 video_track_observers_.push_back( | |
| 186 new RemoteMediaStreamTrackAdapter(video_track, | |
| 187 webkit_video_tracks[i])); | |
| 188 } | |
| 189 | |
| 190 webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()), | |
| 191 webkit_audio_tracks, webkit_video_tracks); | |
| 192 webkit_stream_.setExtraData(new MediaStream(webrtc_stream)); | |
| 193 } | 312 } |
| 194 | 313 |
| 195 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { | 314 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { |
| 315 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 196 webrtc_stream_->UnregisterObserver(this); | 316 webrtc_stream_->UnregisterObserver(this); |
| 197 } | 317 } |
| 198 | 318 |
| 319 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) { | |
| 320 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 321 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( | |
| 322 audio_track_observers_.size()); | |
| 323 for (size_t i = 0; i < audio_track_observers_.size(); ++i) { | |
| 324 audio_track_observers_[i]->Initialize(); | |
| 325 webkit_audio_tracks[i] = *audio_track_observers_[i]->webkit_track(); | |
| 326 } | |
| 327 | |
| 328 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( | |
| 329 video_track_observers_.size()); | |
| 330 for (size_t i = 0; i < video_track_observers_.size(); ++i) { | |
| 331 video_track_observers_[i]->Initialize(); | |
| 332 webkit_video_tracks[i] = *video_track_observers_[i]->webkit_track(); | |
| 333 } | |
| 334 | |
| 335 webkit_stream_.initialize(base::UTF8ToUTF16(label), | |
| 336 webkit_audio_tracks, webkit_video_tracks); | |
| 337 webkit_stream_.setExtraData(new MediaStream(webrtc_stream_.get())); | |
| 338 } | |
| 339 | |
| 199 void RemoteMediaStreamImpl::OnChanged() { | 340 void RemoteMediaStreamImpl::OnChanged() { |
| 200 // Find removed audio tracks. | 341 scoped_ptr<RemoteAudioTrackAdapters> audio(new RemoteAudioTrackAdapters()); |
| 201 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it = | 342 scoped_ptr<RemoteVideoTrackAdapters> video(new RemoteVideoTrackAdapters()); |
| 202 audio_track_observers_.begin(); | 343 |
| 344 CreateAdaptersForTracks( | |
| 345 webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_); | |
| 346 CreateAdaptersForTracks( | |
| 347 webrtc_stream_->GetVideoTracks(), video.get(), main_thread_); | |
| 348 | |
| 349 // TODO(tommi): Unretained safe? | |
|
perkj_chrome
2014/10/31 08:37:24
We must figure that out.
OnChanged here is called
tommi (sloooow) - chröme
2014/10/31 10:06:32
I'll implement an observer pattern like I did else
| |
| 350 main_thread_->PostTask(FROM_HERE, | |
| 351 base::Bind(&RemoteMediaStreamImpl::OnChangedOnMainThread, | |
| 352 base::Unretained(this), base::Passed(&audio), base::Passed(&video))); | |
| 353 } | |
| 354 | |
| 355 void RemoteMediaStreamImpl::OnChangedOnMainThread( | |
| 356 scoped_ptr<RemoteAudioTrackAdapters> audio_tracks, | |
| 357 scoped_ptr<RemoteVideoTrackAdapters> video_tracks) { | |
| 358 // Find removed tracks. | |
| 359 auto audio_it = audio_track_observers_.begin(); | |
| 203 while (audio_it != audio_track_observers_.end()) { | 360 while (audio_it != audio_track_observers_.end()) { |
| 204 std::string track_id = (*audio_it)->observed_track()->id(); | 361 if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) { |
| 205 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { | 362 webkit_stream_.removeTrack(*(*audio_it)->webkit_track()); |
| 206 webkit_stream_.removeTrack((*audio_it)->webkit_track()); | |
| 207 audio_it = audio_track_observers_.erase(audio_it); | 363 audio_it = audio_track_observers_.erase(audio_it); |
| 208 } else { | 364 } else { |
| 209 ++audio_it; | 365 ++audio_it; |
| 210 } | 366 } |
| 211 } | 367 } |
| 212 | 368 |
| 213 // Find removed video tracks. | 369 auto video_it = video_track_observers_.begin(); |
| 214 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator video_it = | |
| 215 video_track_observers_.begin(); | |
| 216 while (video_it != video_track_observers_.end()) { | 370 while (video_it != video_track_observers_.end()) { |
| 217 std::string track_id = (*video_it)->observed_track()->id(); | 371 if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) { |
| 218 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { | 372 webkit_stream_.removeTrack(*(*video_it)->webkit_track()); |
| 219 webkit_stream_.removeTrack((*video_it)->webkit_track()); | |
| 220 video_it = video_track_observers_.erase(video_it); | 373 video_it = video_track_observers_.erase(video_it); |
| 221 } else { | 374 } else { |
| 222 ++video_it; | 375 ++video_it; |
| 223 } | 376 } |
| 224 } | 377 } |
| 225 | 378 |
| 226 // Find added audio tracks. | 379 // Find added tracks. |
| 227 webrtc::AudioTrackVector webrtc_audio_tracks = | 380 for (const auto& track : *audio_tracks.get()) { |
| 228 webrtc_stream_->GetAudioTracks(); | 381 if (!IsTrackInVector(audio_track_observers_, track->id())) { |
| 229 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); | 382 track->Initialize(); |
| 230 it != webrtc_audio_tracks.end(); ++it) { | 383 audio_track_observers_.push_back(track); |
| 231 if (!FindTrackObserver(*it, audio_track_observers_)) { | 384 webkit_stream_.addTrack(*track->webkit_track()); |
| 232 blink::WebMediaStreamTrack new_track; | |
| 233 InitializeWebkitTrack(*it, &new_track, | |
| 234 blink::WebMediaStreamSource::TypeAudio); | |
| 235 audio_track_observers_.push_back( | |
| 236 new RemoteAudioMediaStreamTrackAdapter(*it, new_track)); | |
| 237 webkit_stream_.addTrack(new_track); | |
| 238 } | 385 } |
| 239 } | 386 } |
| 240 | 387 |
| 241 // Find added video tracks. | 388 // Find added video tracks. |
| 242 webrtc::VideoTrackVector webrtc_video_tracks = | 389 for (const auto& track : *video_tracks.get()) { |
| 243 webrtc_stream_->GetVideoTracks(); | 390 if (!IsTrackInVector(video_track_observers_, track->id())) { |
| 244 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); | 391 track->Initialize(); |
| 245 it != webrtc_video_tracks.end(); ++it) { | 392 video_track_observers_.push_back(track); |
| 246 if (!FindTrackObserver(*it, video_track_observers_)) { | 393 webkit_stream_.addTrack(*track->webkit_track()); |
| 247 blink::WebMediaStreamTrack new_track; | |
| 248 InitializeWebkitTrack(*it, &new_track, | |
| 249 blink::WebMediaStreamSource::TypeVideo); | |
| 250 video_track_observers_.push_back( | |
| 251 new RemoteMediaStreamTrackAdapter(*it, new_track)); | |
| 252 webkit_stream_.addTrack(new_track); | |
| 253 } | 394 } |
| 254 } | 395 } |
| 255 } | 396 } |
| 256 | 397 |
| 257 } // namespace content | 398 } // namespace content |
| OLD | NEW |