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

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: 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);
foolip 2017/07/05 08:49:44 Can a DCHECK be added here or in the management of
Guido Urdaneta 2017/07/05 13:05:02 RemoveObserver DCHECKs that its observer argument
foolip 2017/07/05 13:13:52 Yep.
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 }
foolip 2017/07/05 08:49:44 Blank lines between functions seems to be the norm
Guido Urdaneta 2017/07/05 13:05:02 Done.
294 void WebMediaPlayerMS::TrackRemoved(const blink::WebMediaStreamTrack& track) {
295 Reload();
296 }
297 void WebMediaPlayerMS::Reload() {
298 DCHECK(thread_checker_.CalledOnValidThread());
299
300 blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
301 web_stream_.VideoTracks(video_tracks);
302 bool has_video_track = !video_tracks.IsEmpty() &&
303 MediaStreamVideoTrack::GetTrack(video_tracks[0]);
304
305 if (has_video_track && !video_frame_provider_) {
306 // Video track was added.
307 video_frame_provider_ = renderer_factory_->GetVideoRenderer(
308 web_stream_,
309 media::BindToCurrentLoop(
310 base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
311 frame_deliverer_->GetRepaintCallback(), io_task_runner_,
312 media_task_runner_, worker_task_runner_, gpu_factories_);
313 DCHECK(video_frame_provider_);
314 video_frame_provider_->Start();
315 } else if (video_frame_provider_ && !has_video_track) {
316 // Video track was removed.
317 video_frame_provider_->Stop();
318 video_frame_provider_ = nullptr;
319 }
320
321 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_);
322 if (frame) {
323 blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
324 web_stream_.AudioTracks(audio_tracks);
foolip 2017/07/05 08:49:44 Can you add a comment explaining that this is a ge
Guido Urdaneta 2017/07/05 13:05:02 Done. Also for VideoTracks above.
325 bool has_audio_track = !audio_tracks.IsEmpty() &&
326 MediaStreamAudioTrack::GetTrack(audio_tracks[0]);
327
328 if (has_audio_track && !audio_renderer_) {
329 // Audio track was added.
330 audio_renderer_ = renderer_factory_->GetAudioRenderer(
331 web_stream_, frame->GetRoutingID(), initial_audio_output_device_id_,
332 initial_security_origin_);
333 audio_renderer_->SetVolume(volume_);
334 audio_renderer_->Start();
335 audio_renderer_->Play();
336 } else if (!has_audio_track && audio_renderer_) {
337 // Audio track was removed.
338 audio_renderer_->Stop();
339 audio_renderer_ = nullptr;
340 }
341 }
342 }
343
278 void WebMediaPlayerMS::Play() { 344 void WebMediaPlayerMS::Play() {
279 DVLOG(1) << __func__; 345 DVLOG(1) << __func__;
280 DCHECK(thread_checker_.CalledOnValidThread()); 346 DCHECK(thread_checker_.CalledOnValidThread());
281 347
282 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); 348 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
283 if (!paused_) 349 if (!paused_)
284 return; 350 return;
285 351
286 if (video_frame_provider_) 352 if (video_frame_provider_)
287 video_frame_provider_->Resume(); 353 video_frame_provider_->Resume();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 return (video_frame_provider_.get() != nullptr); 440 return (video_frame_provider_.get() != nullptr);
375 } 441 }
376 442
377 bool WebMediaPlayerMS::HasAudio() const { 443 bool WebMediaPlayerMS::HasAudio() const {
378 DCHECK(thread_checker_.CalledOnValidThread()); 444 DCHECK(thread_checker_.CalledOnValidThread());
379 return (audio_renderer_.get() != nullptr); 445 return (audio_renderer_.get() != nullptr);
380 } 446 }
381 447
382 blink::WebSize WebMediaPlayerMS::NaturalSize() const { 448 blink::WebSize WebMediaPlayerMS::NaturalSize() const {
383 DCHECK(thread_checker_.CalledOnValidThread()); 449 DCHECK(thread_checker_.CalledOnValidThread());
450 if (!video_frame_provider_)
451 return blink::WebSize();
452
384 if (video_rotation_ == media::VIDEO_ROTATION_90 || 453 if (video_rotation_ == media::VIDEO_ROTATION_90 ||
385 video_rotation_ == media::VideoRotation::VIDEO_ROTATION_270) { 454 video_rotation_ == media::VideoRotation::VIDEO_ROTATION_270) {
386 const gfx::Size& current_size = compositor_->GetCurrentSize(); 455 const gfx::Size& current_size = compositor_->GetCurrentSize();
387 return blink::WebSize(current_size.height(), current_size.width()); 456 return blink::WebSize(current_size.height(), current_size.width());
388 } 457 }
389 return blink::WebSize(compositor_->GetCurrentSize()); 458 return blink::WebSize(compositor_->GetCurrentSize());
390 } 459 }
391 460
392 bool WebMediaPlayerMS::Paused() const { 461 bool WebMediaPlayerMS::Paused() const {
393 DCHECK(thread_checker_.CalledOnValidThread()); 462 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 video_renderer_.ResetCache(); 790 video_renderer_.ResetCache();
722 } 791 }
723 792
724 void WebMediaPlayerMS::TriggerResize() { 793 void WebMediaPlayerMS::TriggerResize() {
725 get_client()->SizeChanged(); 794 get_client()->SizeChanged();
726 795
727 delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize()); 796 delegate_->DidPlayerSizeChange(delegate_id_, NaturalSize());
728 } 797 }
729 798
730 } // namespace content 799 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698