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

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

Issue 2969093002: Make rendering of MediaStreams reflect changes to its set of tracks. (Closed)
Patch Set: rebase and address comments by foolip@ Created 3 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/webmediaplayer_ms.h" 5 #include "content/renderer/media/webmediaplayer_ms.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "build/build_config.h" 15 #include "build/build_config.h"
16 #include "cc/blink/web_layer_impl.h" 16 #include "cc/blink/web_layer_impl.h"
17 #include "cc/layers/video_frame_provider_client_impl.h" 17 #include "cc/layers/video_frame_provider_client_impl.h"
18 #include "cc/layers/video_layer.h" 18 #include "cc/layers/video_layer.h"
19 #include "content/child/child_process.h" 19 #include "content/child/child_process.h"
20 #include "content/public/renderer/media_stream_audio_renderer.h" 20 #include "content/public/renderer/media_stream_audio_renderer.h"
21 #include "content/public/renderer/media_stream_renderer_factory.h" 21 #include "content/public/renderer/media_stream_renderer_factory.h"
22 #include "content/public/renderer/media_stream_video_renderer.h" 22 #include "content/public/renderer/media_stream_video_renderer.h"
23 #include "content/renderer/media/media_stream_audio_track.h"
24 #include "content/renderer/media/media_stream_video_track.h"
23 #include "content/renderer/media/web_media_element_source_utils.h" 25 #include "content/renderer/media/web_media_element_source_utils.h"
24 #include "content/renderer/media/webmediaplayer_ms_compositor.h" 26 #include "content/renderer/media/webmediaplayer_ms_compositor.h"
25 #include "content/renderer/render_frame_impl.h" 27 #include "content/renderer/render_frame_impl.h"
26 #include "content/renderer/render_thread_impl.h" 28 #include "content/renderer/render_thread_impl.h"
27 #include "media/base/bind_to_current_loop.h" 29 #include "media/base/bind_to_current_loop.h"
28 #include "media/base/media_content_type.h" 30 #include "media/base/media_content_type.h"
29 #include "media/base/media_log.h" 31 #include "media/base/media_log.h"
30 #include "media/base/video_frame.h" 32 #include "media/base/video_frame.h"
31 #include "media/base/video_rotation.h" 33 #include "media/base/video_rotation.h"
32 #include "media/base/video_types.h" 34 #include "media/base/video_types.h"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 delegate_id_ = delegate_->AddObserver(this); 185 delegate_id_ = delegate_->AddObserver(this);
184 186
185 media_log_->AddEvent( 187 media_log_->AddEvent(
186 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 188 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
187 } 189 }
188 190
189 WebMediaPlayerMS::~WebMediaPlayerMS() { 191 WebMediaPlayerMS::~WebMediaPlayerMS() {
190 DVLOG(1) << __func__; 192 DVLOG(1) << __func__;
191 DCHECK(thread_checker_.CalledOnValidThread()); 193 DCHECK(thread_checker_.CalledOnValidThread());
192 194
195 if (!web_stream_.IsNull()) {
196 MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
197 if (native_stream)
198 native_stream->RemoveObserver(this);
199 }
200
193 // Destruct compositor resources in the proper order. 201 // Destruct compositor resources in the proper order.
194 get_client()->SetWebLayer(nullptr); 202 get_client()->SetWebLayer(nullptr);
195 if (video_weblayer_) 203 if (video_weblayer_)
196 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); 204 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider();
197 205
198 if (frame_deliverer_) 206 if (frame_deliverer_)
199 io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release()); 207 io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
200 208
201 if (compositor_) 209 if (compositor_)
202 compositor_->StopUsingProvider(); 210 compositor_->StopUsingProvider();
(...skipping 13 matching lines...) Expand all
216 224
217 void WebMediaPlayerMS::Load(LoadType load_type, 225 void WebMediaPlayerMS::Load(LoadType load_type,
218 const blink::WebMediaPlayerSource& source, 226 const blink::WebMediaPlayerSource& source,
219 CORSMode /*cors_mode*/) { 227 CORSMode /*cors_mode*/) {
220 DVLOG(1) << __func__; 228 DVLOG(1) << __func__;
221 DCHECK(thread_checker_.CalledOnValidThread()); 229 DCHECK(thread_checker_.CalledOnValidThread());
222 230
223 // TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream) 231 // TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream)
224 // once Blink-side changes land. 232 // once Blink-side changes land.
225 DCHECK_NE(load_type, kLoadTypeMediaSource); 233 DCHECK_NE(load_type, kLoadTypeMediaSource);
226 blink::WebMediaStream web_stream = 234 web_stream_ = GetWebMediaStreamFromWebMediaPlayerSource(source);
227 GetWebMediaStreamFromWebMediaPlayerSource(source); 235 if (!web_stream_.IsNull()) {
236 MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
237 if (native_stream)
238 native_stream->AddObserver(this);
239 }
228 240
229 compositor_ = new WebMediaPlayerMSCompositor( 241 compositor_ = new WebMediaPlayerMSCompositor(
230 compositor_task_runner_, io_task_runner_, web_stream, AsWeakPtr()); 242 compositor_task_runner_, io_task_runner_, web_stream_, AsWeakPtr());
231 243
232 SetNetworkState(WebMediaPlayer::kNetworkStateLoading); 244 SetNetworkState(WebMediaPlayer::kNetworkStateLoading);
233 SetReadyState(WebMediaPlayer::kReadyStateHaveNothing); 245 SetReadyState(WebMediaPlayer::kReadyStateHaveNothing);
234 std::string stream_id = 246 std::string stream_id =
235 web_stream.IsNull() ? std::string() : web_stream.Id().Utf8(); 247 web_stream_.IsNull() ? std::string() : web_stream_.Id().Utf8();
236 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); 248 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id));
237 249
238 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer( 250 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer(
239 AsWeakPtr(), 251 AsWeakPtr(),
240 base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, compositor_))); 252 base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, compositor_)));
241 video_frame_provider_ = renderer_factory_->GetVideoRenderer( 253 video_frame_provider_ = renderer_factory_->GetVideoRenderer(
242 web_stream, media::BindToCurrentLoop(base::Bind( 254 web_stream_,
243 &WebMediaPlayerMS::OnSourceError, AsWeakPtr())), 255 media::BindToCurrentLoop(
256 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
244 frame_deliverer_->GetRepaintCallback(), io_task_runner_, 257 frame_deliverer_->GetRepaintCallback(), io_task_runner_,
245 media_task_runner_, worker_task_runner_, gpu_factories_); 258 media_task_runner_, worker_task_runner_, gpu_factories_);
246 259
247 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); 260 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_);
248 261
249 if (frame) { 262 if (frame) {
250 // Report UMA and RAPPOR metrics. 263 // Report UMA and RAPPOR metrics.
251 GURL url = source.IsURL() ? GURL(source.GetAsURL()) : GURL(); 264 GURL url = source.IsURL() ? GURL(source.GetAsURL()) : GURL();
252 media::ReportMetrics(load_type, url, frame_->GetSecurityOrigin(), 265 media::ReportMetrics(load_type, url, frame_->GetSecurityOrigin(),
253 media_log_.get()); 266 media_log_.get());
254 267
255 audio_renderer_ = renderer_factory_->GetAudioRenderer( 268 audio_renderer_ = renderer_factory_->GetAudioRenderer(
256 web_stream, frame->GetRoutingID(), initial_audio_output_device_id_, 269 web_stream_, frame->GetRoutingID(), initial_audio_output_device_id_,
257 initial_security_origin_); 270 initial_security_origin_);
258 } 271 }
259 272
260 if (!video_frame_provider_ && !audio_renderer_) { 273 if (!video_frame_provider_ && !audio_renderer_) {
261 SetNetworkState(WebMediaPlayer::kNetworkStateNetworkError); 274 SetNetworkState(WebMediaPlayer::kNetworkStateNetworkError);
262 return; 275 return;
263 } 276 }
264 277
265 if (audio_renderer_) { 278 if (audio_renderer_) {
266 audio_renderer_->SetVolume(volume_); 279 audio_renderer_->SetVolume(volume_);
267 audio_renderer_->Start(); 280 audio_renderer_->Start();
268 } 281 }
269 if (video_frame_provider_) 282 if (video_frame_provider_)
270 video_frame_provider_->Start(); 283 video_frame_provider_->Start();
271 if (audio_renderer_ && !video_frame_provider_) { 284 if (audio_renderer_ && !video_frame_provider_) {
272 // This is audio-only mode. 285 // This is audio-only mode.
273 SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata); 286 SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
274 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); 287 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData);
275 } 288 }
276 } 289 }
277 290
291 void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) {
292 Reload();
293 }
294
295 void WebMediaPlayerMS::TrackRemoved(const blink::WebMediaStreamTrack& track) {
296 Reload();
297 }
298
299 void WebMediaPlayerMS::Reload() {
300 DCHECK(thread_checker_.CalledOnValidThread());
301
302 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
303 // VideoTracks() is a getter.
304 web_stream_.VideoTracks(video_tracks);
305 bool has_video_track = !video_tracks.IsEmpty() &&
emircan 2017/07/05 18:04:09 const
Guido Urdaneta 2017/07/06 18:50:33 Removed.
306 MediaStreamVideoTrack::GetTrack(video_tracks[0]);
307
308 if (has_video_track && !video_frame_provider_) {
emircan 2017/07/05 18:04:09 I have a question regarding multiple video track c
Guido Urdaneta 2017/07/05 19:01:08 Good question. I'll check what other browsers do a
Guido Urdaneta 2017/07/06 18:50:33 Edge only plays a mediaStream if it has a single t
309 // Video track was added.
310 video_frame_provider_ = renderer_factory_->GetVideoRenderer(
311 web_stream_,
312 media::BindToCurrentLoop(
313 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
314 frame_deliverer_->GetRepaintCallback(), io_task_runner_,
315 media_task_runner_, worker_task_runner_, gpu_factories_);
316 DCHECK(video_frame_provider_);
317 video_frame_provider_->Start();
emircan 2017/07/05 18:04:09 You should also cover the uses of WebMediaPlayerMS
Guido Urdaneta 2017/07/05 19:01:08 Can you elaborate a bit since I don't have the ful
emircan 2017/07/05 19:45:57 RendererWebMediaPlayerDelegate::DidPlay() [0] keep
Guido Urdaneta 2017/07/06 18:50:33 As discussed offline, calling DidPlay twice causes
318 } else if (video_frame_provider_ && !has_video_track) {
319 // Video track was removed.
320 video_frame_provider_->Stop();
321 video_frame_provider_ = nullptr;
322 }
323
324 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_);
325 if (frame) {
326 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
327 // AudioTracks() is a getter.
328 web_stream_.AudioTracks(audio_tracks);
329 bool has_audio_track = !audio_tracks.IsEmpty() &&
330 MediaStreamAudioTrack::GetTrack(audio_tracks[0]);
331
332 if (has_audio_track && !audio_renderer_) {
333 // Audio track was added.
334 audio_renderer_ = renderer_factory_->GetAudioRenderer(
335 web_stream_, frame->GetRoutingID(), initial_audio_output_device_id_,
336 initial_security_origin_);
337 audio_renderer_->SetVolume(volume_);
338 audio_renderer_->Start();
339 audio_renderer_->Play();
340 } else if (!has_audio_track && audio_renderer_) {
341 // Audio track was removed.
342 audio_renderer_->Stop();
343 audio_renderer_ = nullptr;
344 }
345 }
346 }
347
278 void WebMediaPlayerMS::Play() { 348 void WebMediaPlayerMS::Play() {
279 DVLOG(1) << __func__; 349 DVLOG(1) << __func__;
280 DCHECK(thread_checker_.CalledOnValidThread()); 350 DCHECK(thread_checker_.CalledOnValidThread());
281 351
282 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); 352 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
283 if (!paused_) 353 if (!paused_)
284 return; 354 return;
285 355
286 if (video_frame_provider_) 356 if (video_frame_provider_)
287 video_frame_provider_->Resume(); 357 video_frame_provider_->Resume();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 return (video_frame_provider_.get() != nullptr); 444 return (video_frame_provider_.get() != nullptr);
375 } 445 }
376 446
377 bool WebMediaPlayerMS::HasAudio() const { 447 bool WebMediaPlayerMS::HasAudio() const {
378 DCHECK(thread_checker_.CalledOnValidThread()); 448 DCHECK(thread_checker_.CalledOnValidThread());
379 return (audio_renderer_.get() != nullptr); 449 return (audio_renderer_.get() != nullptr);
380 } 450 }
381 451
382 blink::WebSize WebMediaPlayerMS::NaturalSize() const { 452 blink::WebSize WebMediaPlayerMS::NaturalSize() const {
383 DCHECK(thread_checker_.CalledOnValidThread()); 453 DCHECK(thread_checker_.CalledOnValidThread());
454 if (!video_frame_provider_)
455 return blink::WebSize();
456
384 if (video_rotation_ == media::VIDEO_ROTATION_90 || 457 if (video_rotation_ == media::VIDEO_ROTATION_90 ||
385 video_rotation_ == media::VideoRotation::VIDEO_ROTATION_270) { 458 video_rotation_ == media::VideoRotation::VIDEO_ROTATION_270) {
386 const gfx::Size& current_size = compositor_->GetCurrentSize(); 459 const gfx::Size& current_size = compositor_->GetCurrentSize();
387 return blink::WebSize(current_size.height(), current_size.width()); 460 return blink::WebSize(current_size.height(), current_size.width());
388 } 461 }
389 return blink::WebSize(compositor_->GetCurrentSize()); 462 return blink::WebSize(compositor_->GetCurrentSize());
390 } 463 }
391 464
392 bool WebMediaPlayerMS::Paused() const { 465 bool WebMediaPlayerMS::Paused() const {
393 DCHECK(thread_checker_.CalledOnValidThread()); 466 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 video_renderer_.ResetCache(); 794 video_renderer_.ResetCache();
722 } 795 }
723 796
724 void WebMediaPlayerMS::TriggerResize() { 797 void WebMediaPlayerMS::TriggerResize() {
725 get_client()->SizeChanged(); 798 get_client()->SizeChanged();
726 799
727 delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize()); 800 delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
728 } 801 }
729 802
730 } // namespace content 803 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698