Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: content/renderer/media/remote_media_stream_impl.cc

Issue 2883023002: WebRtcMediaStreamTrackAdapter, maps 1 webrtc and 1 blink track (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698