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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/location.h" | 13 #include "base/location.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/strings/utf_string_conversions.h" | |
| 17 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "content/renderer/media/media_stream.h" | 17 #include "content/renderer/media/media_stream.h" |
| 19 #include "content/renderer/media/media_stream_track.h" | 18 #include "content/renderer/media/media_stream_track.h" |
| 20 #include "content/renderer/media/media_stream_video_track.h" | 19 #include "content/renderer/media/media_stream_video_track.h" |
| 20 #include "content/renderer/media/remote_media_stream_track_adapter.h" | |
|
hbos_chromium
2017/05/18 11:41:51
RemoteMediaStreamTrackAdapter, RemoteVideoTrackAda
| |
| 21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" | 21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" |
| 22 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | |
| 23 #include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h" | |
| 24 #include "content/renderer/media/webrtc/track_observer.h" | |
| 25 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | |
| 26 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| 27 #include "third_party/WebKit/public/platform/WebString.h" | 23 #include "third_party/WebKit/public/platform/WebString.h" |
| 28 | 24 |
| 29 namespace content { | 25 namespace content { |
| 30 namespace { | 26 namespace { |
| 31 | 27 |
| 32 template <typename WebRtcTrackVector, typename AdapterType> | 28 template <typename WebRtcTrackVector, typename AdapterType> |
| 33 void CreateAdaptersForTracks( | 29 void CreateAdaptersForTracks( |
| 34 const WebRtcTrackVector& tracks, | 30 const WebRtcTrackVector& tracks, |
| 35 std::vector<scoped_refptr<AdapterType>>* observers, | 31 std::vector<scoped_refptr<AdapterType>>* observers, |
| 36 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { | 32 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { |
| 37 for (auto& track : tracks) | 33 for (auto& track : tracks) |
| 38 observers->push_back(new AdapterType(main_thread, track)); | 34 observers->push_back(new AdapterType(main_thread, track)); |
| 39 } | 35 } |
| 40 | 36 |
| 41 template<typename VectorType> | 37 template<typename VectorType> |
| 42 bool IsTrackInVector(const VectorType& v, const std::string& id) { | 38 bool IsTrackInVector(const VectorType& v, const std::string& id) { |
| 43 for (const auto& t : v) { | 39 for (const auto& t : v) { |
| 44 if (t->id() == id) | 40 if (t->id() == id) |
| 45 return true; | 41 return true; |
| 46 } | 42 } |
| 47 return false; | 43 return false; |
| 48 } | 44 } |
| 49 } // namespace | 45 } // namespace |
| 50 | 46 |
| 51 // Base class used for mapping between webrtc and blink MediaStream tracks. | |
| 52 // An instance of a RemoteMediaStreamTrackAdapter is stored in | |
| 53 // RemoteMediaStreamImpl per remote audio and video track. | |
| 54 template<typename WebRtcMediaStreamTrackType> | |
| 55 class RemoteMediaStreamTrackAdapter | |
| 56 : public base::RefCountedThreadSafe< | |
| 57 RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>> { | |
| 58 public: | |
| 59 RemoteMediaStreamTrackAdapter( | |
| 60 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 61 WebRtcMediaStreamTrackType* webrtc_track) | |
| 62 : main_thread_(main_thread), webrtc_track_(webrtc_track), | |
| 63 id_(webrtc_track->id()) { | |
| 64 } | |
| 65 | |
| 66 const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() { | |
| 67 return webrtc_track_; | |
| 68 } | |
| 69 | |
| 70 blink::WebMediaStreamTrack* webkit_track() { | |
| 71 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 72 DCHECK(!webkit_track_.IsNull()); | |
| 73 return &webkit_track_; | |
| 74 } | |
| 75 | |
| 76 const std::string& id() const { return id_; } | |
| 77 | |
| 78 bool initialized() const { | |
| 79 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 80 return !webkit_track_.IsNull(); | |
| 81 } | |
| 82 | |
| 83 void Initialize() { | |
| 84 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 85 DCHECK(!initialized()); | |
| 86 webkit_initialize_.Run(); | |
| 87 webkit_initialize_.Reset(); | |
| 88 DCHECK(initialized()); | |
| 89 } | |
| 90 | |
| 91 protected: | |
| 92 friend class base::RefCountedThreadSafe< | |
| 93 RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>>; | |
| 94 | |
| 95 virtual ~RemoteMediaStreamTrackAdapter() { | |
| 96 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 97 } | |
| 98 | |
| 99 void InitializeWebkitTrack(blink::WebMediaStreamSource::Type type) { | |
| 100 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 101 DCHECK(webkit_track_.IsNull()); | |
| 102 | |
| 103 blink::WebString webkit_track_id(blink::WebString::FromUTF8(id_)); | |
| 104 blink::WebMediaStreamSource webkit_source; | |
| 105 webkit_source.Initialize(webkit_track_id, type, webkit_track_id, | |
| 106 true /* remote */); | |
| 107 webkit_track_.Initialize(webkit_track_id, webkit_source); | |
| 108 DCHECK(!webkit_track_.IsNull()); | |
| 109 } | |
| 110 | |
| 111 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; | |
| 112 // This callback will be run when Initialize() is called and then freed. | |
| 113 // The callback is used by derived classes to bind objects that need to be | |
| 114 // instantiated and initialized on the signaling thread but then moved to | |
| 115 // and used on the main thread when initializing the webkit object(s). | |
| 116 base::Callback<void()> webkit_initialize_; | |
| 117 | |
| 118 private: | |
| 119 const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_; | |
| 120 blink::WebMediaStreamTrack webkit_track_; | |
| 121 // const copy of the webrtc track id that allows us to check it from both the | |
| 122 // main and signaling threads without incurring a synchronous thread hop. | |
| 123 const std::string id_; | |
| 124 | |
| 125 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); | |
| 126 }; | |
| 127 | |
| 128 class RemoteVideoTrackAdapter | |
| 129 : public RemoteMediaStreamTrackAdapter<webrtc::VideoTrackInterface> { | |
| 130 public: | |
| 131 // Called on the signaling thread | |
| 132 RemoteVideoTrackAdapter( | |
| 133 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 134 webrtc::VideoTrackInterface* webrtc_track) | |
| 135 : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track) { | |
| 136 std::unique_ptr<TrackObserver> observer( | |
| 137 new TrackObserver(main_thread, observed_track().get())); | |
| 138 // Here, we use base::Unretained() to avoid a circular reference. | |
| 139 webkit_initialize_ = base::Bind( | |
| 140 &RemoteVideoTrackAdapter::InitializeWebkitVideoTrack, | |
| 141 base::Unretained(this), base::Passed(&observer), | |
| 142 observed_track()->enabled()); | |
| 143 } | |
| 144 | |
| 145 protected: | |
| 146 ~RemoteVideoTrackAdapter() override { | |
| 147 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 148 if (initialized()) { | |
| 149 static_cast<MediaStreamRemoteVideoSource*>( | |
| 150 webkit_track()->Source().GetExtraData()) | |
| 151 ->OnSourceTerminated(); | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 private: | |
| 156 void InitializeWebkitVideoTrack(std::unique_ptr<TrackObserver> observer, | |
| 157 bool enabled) { | |
| 158 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 159 std::unique_ptr<MediaStreamRemoteVideoSource> video_source( | |
| 160 new MediaStreamRemoteVideoSource(std::move(observer))); | |
| 161 InitializeWebkitTrack(blink::WebMediaStreamSource::kTypeVideo); | |
| 162 webkit_track()->Source().SetExtraData(video_source.get()); | |
| 163 MediaStreamVideoTrack* media_stream_track = new MediaStreamVideoTrack( | |
| 164 video_source.release(), MediaStreamVideoSource::ConstraintsCallback(), | |
| 165 enabled); | |
| 166 webkit_track()->SetTrackData(media_stream_track); | |
| 167 } | |
| 168 }; | |
| 169 | |
| 170 // RemoteAudioTrackAdapter is responsible for listening on state | |
| 171 // change notifications on a remote webrtc audio MediaStreamTracks and notify | |
| 172 // WebKit. | |
| 173 class RemoteAudioTrackAdapter | |
| 174 : public RemoteMediaStreamTrackAdapter<webrtc::AudioTrackInterface>, | |
| 175 public webrtc::ObserverInterface { | |
| 176 public: | |
| 177 RemoteAudioTrackAdapter( | |
| 178 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 179 webrtc::AudioTrackInterface* webrtc_track); | |
| 180 | |
| 181 void Unregister(); | |
| 182 | |
| 183 protected: | |
| 184 ~RemoteAudioTrackAdapter() override; | |
| 185 | |
| 186 private: | |
| 187 void InitializeWebkitAudioTrack(); | |
| 188 | |
| 189 // webrtc::ObserverInterface implementation. | |
| 190 void OnChanged() override; | |
| 191 | |
| 192 void OnChangedOnMainThread( | |
| 193 webrtc::MediaStreamTrackInterface::TrackState state); | |
| 194 | |
| 195 #if DCHECK_IS_ON() | |
| 196 bool unregistered_; | |
| 197 #endif | |
| 198 | |
| 199 webrtc::MediaStreamTrackInterface::TrackState state_; | |
| 200 | |
| 201 DISALLOW_COPY_AND_ASSIGN(RemoteAudioTrackAdapter); | |
| 202 }; | |
| 203 | |
| 204 // Called on the signaling thread. | |
| 205 RemoteAudioTrackAdapter::RemoteAudioTrackAdapter( | |
| 206 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | |
| 207 webrtc::AudioTrackInterface* webrtc_track) | |
| 208 : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track), | |
| 209 #if DCHECK_IS_ON() | |
| 210 unregistered_(false), | |
| 211 #endif | |
| 212 state_(observed_track()->state()) { | |
| 213 // TODO(tommi): Use TrackObserver instead. | |
| 214 observed_track()->RegisterObserver(this); | |
| 215 // Here, we use base::Unretained() to avoid a circular reference. | |
| 216 webkit_initialize_ = | |
| 217 base::Bind(&RemoteAudioTrackAdapter::InitializeWebkitAudioTrack, | |
| 218 base::Unretained(this)); | |
| 219 } | |
| 220 | |
| 221 RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() { | |
| 222 #if DCHECK_IS_ON() | |
| 223 DCHECK(unregistered_); | |
| 224 #endif | |
| 225 } | |
| 226 | |
| 227 void RemoteAudioTrackAdapter::Unregister() { | |
| 228 #if DCHECK_IS_ON() | |
| 229 DCHECK(!unregistered_); | |
| 230 unregistered_ = true; | |
| 231 #endif | |
| 232 observed_track()->UnregisterObserver(this); | |
| 233 } | |
| 234 | |
| 235 void RemoteAudioTrackAdapter::InitializeWebkitAudioTrack() { | |
| 236 InitializeWebkitTrack(blink::WebMediaStreamSource::kTypeAudio); | |
| 237 | |
| 238 MediaStreamAudioSource* const source = | |
| 239 new PeerConnectionRemoteAudioSource(observed_track().get()); | |
| 240 webkit_track()->Source().SetExtraData(source); // Takes ownership. | |
| 241 source->ConnectToTrack(*(webkit_track())); | |
| 242 } | |
| 243 | |
| 244 void RemoteAudioTrackAdapter::OnChanged() { | |
| 245 main_thread_->PostTask(FROM_HERE, | |
| 246 base::Bind(&RemoteAudioTrackAdapter::OnChangedOnMainThread, | |
| 247 this, observed_track()->state())); | |
| 248 } | |
| 249 | |
| 250 void RemoteAudioTrackAdapter::OnChangedOnMainThread( | |
| 251 webrtc::MediaStreamTrackInterface::TrackState state) { | |
| 252 DCHECK(main_thread_->BelongsToCurrentThread()); | |
| 253 | |
| 254 if (state == state_ || !initialized()) | |
| 255 return; | |
| 256 | |
| 257 state_ = state; | |
| 258 | |
| 259 switch (state) { | |
| 260 case webrtc::MediaStreamTrackInterface::kLive: | |
| 261 webkit_track()->Source().SetReadyState( | |
| 262 blink::WebMediaStreamSource::kReadyStateLive); | |
| 263 break; | |
| 264 case webrtc::MediaStreamTrackInterface::kEnded: | |
| 265 webkit_track()->Source().SetReadyState( | |
| 266 blink::WebMediaStreamSource::kReadyStateEnded); | |
| 267 break; | |
| 268 default: | |
| 269 NOTREACHED(); | |
| 270 break; | |
| 271 } | |
| 272 } | |
| 273 | |
| 274 RemoteMediaStreamImpl::Observer::Observer( | 47 RemoteMediaStreamImpl::Observer::Observer( |
| 275 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream, | 48 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream, |
| 276 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, | 49 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 277 webrtc::MediaStreamInterface* webrtc_stream) | 50 webrtc::MediaStreamInterface* webrtc_stream) |
| 278 : media_stream_(media_stream), | 51 : media_stream_(media_stream), |
| 279 main_thread_(main_thread), | 52 main_thread_(main_thread), |
| 280 webrtc_stream_(webrtc_stream) { | 53 webrtc_stream_(webrtc_stream) { |
| 281 webrtc_stream_->RegisterObserver(this); | 54 webrtc_stream_->RegisterObserver(this); |
| 282 } | 55 } |
| 283 | 56 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 // Unregister all the audio track observers that were not used. | 192 // Unregister all the audio track observers that were not used. |
| 420 // We need to do this before destruction since the observers can't unregister | 193 // We need to do this before destruction since the observers can't unregister |
| 421 // from within the dtor due to a race. | 194 // from within the dtor due to a race. |
| 422 for (auto& track : *audio_tracks.get()) { | 195 for (auto& track : *audio_tracks.get()) { |
| 423 if (track.get()) | 196 if (track.get()) |
| 424 track->Unregister(); | 197 track->Unregister(); |
| 425 } | 198 } |
| 426 } | 199 } |
| 427 | 200 |
| 428 } // namespace content | 201 } // namespace content |
| OLD | NEW |