OLD | NEW |
---|---|
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 "build/build_config.h" | 15 #include "build/build_config.h" |
15 #include "cc/blink/web_layer_impl.h" | 16 #include "cc/blink/web_layer_impl.h" |
16 #include "cc/layers/video_frame_provider_client_impl.h" | 17 #include "cc/layers/video_frame_provider_client_impl.h" |
17 #include "cc/layers/video_layer.h" | 18 #include "cc/layers/video_layer.h" |
18 #include "content/common/gpu/client/context_provider_command_buffer.h" | 19 #include "content/common/gpu/client/context_provider_command_buffer.h" |
19 #include "content/public/renderer/media_stream_audio_renderer.h" | 20 #include "content/public/renderer/media_stream_audio_renderer.h" |
20 #include "content/public/renderer/media_stream_renderer_factory.h" | 21 #include "content/public/renderer/media_stream_renderer_factory.h" |
21 #include "content/public/renderer/media_stream_video_renderer.h" | 22 #include "content/public/renderer/media_stream_video_renderer.h" |
22 #include "content/renderer/media/web_media_element_source_utils.h" | 23 #include "content/renderer/media/web_media_element_source_utils.h" |
23 #include "content/renderer/media/webmediaplayer_ms_compositor.h" | 24 #include "content/renderer/media/webmediaplayer_ms_compositor.h" |
24 #include "content/renderer/render_frame_impl.h" | 25 #include "content/renderer/render_frame_impl.h" |
25 #include "content/renderer/render_thread_impl.h" | 26 #include "content/renderer/render_thread_impl.h" |
27 #include "media/base/bind_to_current_loop.h" | |
26 #include "media/base/media_content_type.h" | 28 #include "media/base/media_content_type.h" |
27 #include "media/base/media_log.h" | 29 #include "media/base/media_log.h" |
28 #include "media/base/video_frame.h" | 30 #include "media/base/video_frame.h" |
29 #include "media/base/video_rotation.h" | 31 #include "media/base/video_rotation.h" |
30 #include "media/base/video_types.h" | 32 #include "media/base/video_types.h" |
31 #include "media/blink/webmediaplayer_util.h" | 33 #include "media/blink/webmediaplayer_util.h" |
32 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" | 34 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" |
33 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" | 35 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" |
34 #include "third_party/WebKit/public/platform/WebRect.h" | 36 #include "third_party/WebKit/public/platform/WebRect.h" |
35 #include "third_party/WebKit/public/platform/WebSize.h" | 37 #include "third_party/WebKit/public/platform/WebSize.h" |
36 | 38 |
37 namespace content { | 39 namespace content { |
38 | 40 |
41 // FrameDelivererOnCompositor is responsible for delivering frames received on | |
42 // compositor thread by calling of EnqueueFrame() method of |compositor_|. | |
43 // | |
44 // It is created on main thread, but methods should be called and class should | |
45 // be destructed on compositor thread. | |
46 class WebMediaPlayerMS::FrameDelivererOnCompositor { | |
47 public: | |
48 FrameDelivererOnCompositor( | |
49 const base::WeakPtr<WebMediaPlayerMS>& player, | |
50 const base::WeakPtr<WebMediaPlayerMSCompositor>& compositor) | |
51 : last_frame_opaque_(true), | |
52 received_first_frame_(false), | |
53 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
54 player_(player), | |
55 compositor_(compositor), | |
56 weak_factory_for_compositor_(this) { | |
57 thread_checker_.DetachFromThread(); | |
58 } | |
59 ~FrameDelivererOnCompositor() { | |
60 weak_factory_for_compositor_.InvalidateWeakPtrs(); | |
61 DCHECK(thread_checker_.CalledOnValidThread()); | |
62 } | |
63 | |
64 void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame) { | |
65 DCHECK(thread_checker_.CalledOnValidThread()); | |
66 | |
67 #if defined(OS_ANDROID) | |
68 { | |
69 base::AutoLock auto_lock(render_frame_suspended_lock_); | |
70 if (render_frame_suspended_) | |
71 return; | |
72 } | |
73 #endif // defined(OS_ANDROID) | |
74 | |
75 base::TimeTicks render_time; | |
76 if (frame->metadata()->GetTimeTicks( | |
77 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { | |
78 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable", | |
79 "Ideal Render Instant", render_time.ToInternalValue()); | |
80 } else { | |
81 TRACE_EVENT0("webrtc", "WebMediaPlayerMS::OnFrameAvailable"); | |
82 } | |
83 const bool is_opaque = media::IsOpaque(frame->format()); | |
84 | |
85 if (!received_first_frame_) { | |
86 received_first_frame_ = true; | |
87 last_frame_opaque_ = is_opaque; | |
88 media::VideoRotation video_rotation; | |
89 ignore_result(frame->metadata()->GetRotation( | |
90 media::VideoFrameMetadata::ROTATION, &video_rotation)); | |
91 main_task_runner_->PostTask( | |
qiangchen
2016/11/09 19:44:39
I am worrying that this might be an issue. Theoret
emircan
2016/11/11 22:27:19
Yes, compositor tasks may run on before OnFirstFra
qiangchen
2016/11/15 00:04:54
Never mind. I did some research, it is the "setWeb
| |
92 FROM_HERE, base::Bind(&WebMediaPlayerMS::OnFirstFrameReceived, | |
93 player_, video_rotation, is_opaque)); | |
94 } | |
95 | |
96 if (last_frame_opaque_ != is_opaque) { | |
97 last_frame_opaque_ = is_opaque; | |
98 main_task_runner_->PostTask( | |
99 FROM_HERE, | |
100 base::Bind(&WebMediaPlayerMS::OnOpacityChanged, player_, is_opaque)); | |
101 } | |
102 | |
103 if (compositor_.get()) | |
104 compositor_->EnqueueFrame(frame); | |
105 } | |
106 | |
107 #if defined(OS_ANDROID) | |
108 void SetRenderFrameSuspended(bool render_frame_suspended) { | |
109 base::AutoLock auto_lock(render_frame_suspended_lock_); | |
110 render_frame_suspended_ = render_frame_suspended; | |
111 } | |
112 #endif // defined(OS_ANDROID) | |
113 | |
114 base::WeakPtr<FrameDelivererOnCompositor> GetWeakPtr() { | |
115 return weak_factory_for_compositor_.GetWeakPtr(); | |
116 } | |
117 | |
118 private: | |
119 bool last_frame_opaque_; | |
120 bool received_first_frame_; | |
121 | |
122 #if defined(OS_ANDROID) | |
123 bool render_frame_suspended_ = false; | |
124 base::Lock render_frame_suspended_lock_; | |
125 #endif // defined(OS_ANDROID) | |
126 | |
127 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | |
128 const base::WeakPtr<WebMediaPlayerMS> player_; | |
129 const base::WeakPtr<WebMediaPlayerMSCompositor> compositor_; | |
130 | |
131 // Used for DCHECKs to ensure method calls executed in the correct thread, | |
perkj_chrome
2016/11/09 15:27:13
/s on the
emircan
2016/11/11 22:27:19
Done.
| |
132 // i.e. compositor thread. | |
133 base::ThreadChecker thread_checker_; | |
qiangchen
2016/11/09 19:44:38
nit: Can you rename it to compositor_thread_checke
emircan
2016/11/11 22:27:19
Done.
qiangchen
2016/11/15 00:04:54
Acknowledged.
| |
134 | |
135 base::WeakPtrFactory<FrameDelivererOnCompositor> weak_factory_for_compositor_; | |
136 | |
137 DISALLOW_COPY_AND_ASSIGN(FrameDelivererOnCompositor); | |
138 }; | |
139 | |
39 WebMediaPlayerMS::WebMediaPlayerMS( | 140 WebMediaPlayerMS::WebMediaPlayerMS( |
40 blink::WebFrame* frame, | 141 blink::WebFrame* frame, |
41 blink::WebMediaPlayerClient* client, | 142 blink::WebMediaPlayerClient* client, |
42 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, | 143 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, |
43 media::MediaLog* media_log, | 144 media::MediaLog* media_log, |
44 std::unique_ptr<MediaStreamRendererFactory> factory, | 145 std::unique_ptr<MediaStreamRendererFactory> factory, |
45 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, | 146 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, |
46 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 147 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
47 const scoped_refptr<base::TaskRunner>& worker_task_runner, | 148 const scoped_refptr<base::TaskRunner>& worker_task_runner, |
48 media::GpuVideoAcceleratorFactories* gpu_factories, | 149 media::GpuVideoAcceleratorFactories* gpu_factories, |
49 const blink::WebString& sink_id, | 150 const blink::WebString& sink_id, |
50 const blink::WebSecurityOrigin& security_origin) | 151 const blink::WebSecurityOrigin& security_origin) |
51 : frame_(frame), | 152 : frame_(frame), |
52 network_state_(WebMediaPlayer::NetworkStateEmpty), | 153 network_state_(WebMediaPlayer::NetworkStateEmpty), |
53 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 154 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
54 buffered_(static_cast<size_t>(0)), | 155 buffered_(static_cast<size_t>(0)), |
55 client_(client), | 156 client_(client), |
56 delegate_(delegate), | 157 delegate_(delegate), |
57 delegate_id_(0), | 158 delegate_id_(0), |
58 last_frame_opaque_(true), | |
59 paused_(true), | 159 paused_(true), |
60 render_frame_suspended_(false), | |
61 received_first_frame_(false), | |
62 video_rotation_(media::VIDEO_ROTATION_0), | 160 video_rotation_(media::VIDEO_ROTATION_0), |
63 media_log_(media_log), | 161 media_log_(media_log), |
64 renderer_factory_(std::move(factory)), | 162 renderer_factory_(std::move(factory)), |
65 media_task_runner_(media_task_runner), | 163 media_task_runner_(media_task_runner), |
66 worker_task_runner_(worker_task_runner), | 164 worker_task_runner_(worker_task_runner), |
67 gpu_factories_(gpu_factories), | 165 gpu_factories_(gpu_factories), |
68 compositor_task_runner_(compositor_task_runner), | 166 compositor_task_runner_(compositor_task_runner), |
69 initial_audio_output_device_id_(sink_id.utf8()), | 167 initial_audio_output_device_id_(sink_id.utf8()), |
70 initial_security_origin_(security_origin.isNull() | 168 initial_security_origin_(security_origin.isNull() |
71 ? url::Origin() | 169 ? url::Origin() |
(...skipping 11 matching lines...) Expand all Loading... | |
83 } | 181 } |
84 | 182 |
85 WebMediaPlayerMS::~WebMediaPlayerMS() { | 183 WebMediaPlayerMS::~WebMediaPlayerMS() { |
86 DVLOG(1) << __func__; | 184 DVLOG(1) << __func__; |
87 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
88 | 186 |
89 // Destruct compositor resources in the proper order. | 187 // Destruct compositor resources in the proper order. |
90 get_client()->setWebLayer(nullptr); | 188 get_client()->setWebLayer(nullptr); |
91 if (video_weblayer_) | 189 if (video_weblayer_) |
92 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); | 190 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); |
191 | |
192 if (frame_deliverer_) | |
193 compositor_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release()); | |
194 | |
93 if (compositor_) | 195 if (compositor_) |
94 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release()); | 196 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release()); |
95 | 197 |
96 if (video_frame_provider_) | 198 if (video_frame_provider_) |
97 video_frame_provider_->Stop(); | 199 video_frame_provider_->Stop(); |
98 | 200 |
99 if (audio_renderer_) | 201 if (audio_renderer_) |
100 audio_renderer_->Stop(); | 202 audio_renderer_->Stop(); |
101 | 203 |
102 media_log_->AddEvent( | 204 media_log_->AddEvent( |
(...skipping 19 matching lines...) Expand all Loading... | |
122 | 224 |
123 compositor_.reset(new WebMediaPlayerMSCompositor(compositor_task_runner_, | 225 compositor_.reset(new WebMediaPlayerMSCompositor(compositor_task_runner_, |
124 web_stream, AsWeakPtr())); | 226 web_stream, AsWeakPtr())); |
125 | 227 |
126 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 228 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
127 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); | 229 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); |
128 std::string stream_id = | 230 std::string stream_id = |
129 web_stream.isNull() ? std::string() : web_stream.id().utf8(); | 231 web_stream.isNull() ? std::string() : web_stream.id().utf8(); |
130 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); | 232 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); |
131 | 233 |
234 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDelivererOnCompositor( | |
235 AsWeakPtr(), compositor_->GetWeakPtr())); | |
132 video_frame_provider_ = renderer_factory_->GetVideoRenderer( | 236 video_frame_provider_ = renderer_factory_->GetVideoRenderer( |
133 web_stream, base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()), | 237 web_stream, media::BindToCurrentLoop(base::Bind( |
134 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()), | 238 &WebMediaPlayerMS::OnSourceError, AsWeakPtr())), |
135 media_task_runner_, worker_task_runner_, gpu_factories_); | 239 base::Bind(&FrameDelivererOnCompositor::OnVideoFrame, |
240 frame_deliverer_->GetWeakPtr()), | |
241 compositor_task_runner_, media_task_runner_, worker_task_runner_, | |
242 gpu_factories_); | |
136 | 243 |
137 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); | 244 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); |
138 | 245 |
139 if (frame) { | 246 if (frame) { |
140 // Report UMA and RAPPOR metrics. | 247 // Report UMA and RAPPOR metrics. |
141 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL(); | 248 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL(); |
142 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin()); | 249 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin()); |
143 | 250 |
144 audio_renderer_ = renderer_factory_->GetAudioRenderer( | 251 audio_renderer_ = renderer_factory_->GetAudioRenderer( |
145 web_stream, frame->GetRoutingID(), initial_audio_output_device_id_, | 252 web_stream, frame->GetRoutingID(), initial_audio_output_device_id_, |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
395 void WebMediaPlayerMS::OnHidden() { | 502 void WebMediaPlayerMS::OnHidden() { |
396 #if defined(OS_ANDROID) | 503 #if defined(OS_ANDROID) |
397 DCHECK(thread_checker_.CalledOnValidThread()); | 504 DCHECK(thread_checker_.CalledOnValidThread()); |
398 | 505 |
399 // Method called when the RenderFrame is sent to background and suspended | 506 // Method called when the RenderFrame is sent to background and suspended |
400 // (android). Substitute the displayed VideoFrame with a copy to avoid | 507 // (android). Substitute the displayed VideoFrame with a copy to avoid |
401 // holding on to it unnecessarily. | 508 // holding on to it unnecessarily. |
402 // | 509 // |
403 // During undoable tab closures OnHidden() may be called back to back, so we | 510 // During undoable tab closures OnHidden() may be called back to back, so we |
404 // can't rely on |render_frame_suspended_| being false here. | 511 // can't rely on |render_frame_suspended_| being false here. |
512 if (frame_deliverer_) | |
513 frame_deliverer_->SetRenderFrameSuspended(true); | |
405 | 514 |
406 render_frame_suspended_ = true; | |
407 if (!paused_) | 515 if (!paused_) |
408 compositor_->ReplaceCurrentFrameWithACopy(); | 516 compositor_->ReplaceCurrentFrameWithACopy(); |
409 #endif // defined(OS_ANDROID) | 517 #endif // defined(OS_ANDROID) |
410 } | 518 } |
411 | 519 |
412 void WebMediaPlayerMS::OnShown() { | 520 void WebMediaPlayerMS::OnShown() { |
413 #if defined(OS_ANDROID) | 521 #if defined(OS_ANDROID) |
414 DCHECK(thread_checker_.CalledOnValidThread()); | 522 DCHECK(thread_checker_.CalledOnValidThread()); |
415 | 523 |
416 render_frame_suspended_ = false; | 524 frame_deliverer_->SetRenderFrameSuspended(false); |
417 | 525 |
418 // Resume playback on visibility. play() clears |should_play_upon_shown_|. | 526 // Resume playback on visibility. play() clears |should_play_upon_shown_|. |
419 if (should_play_upon_shown_) | 527 if (should_play_upon_shown_) |
420 play(); | 528 play(); |
421 #endif // defined(OS_ANDROID) | 529 #endif // defined(OS_ANDROID) |
422 } | 530 } |
423 | 531 |
424 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) { | 532 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) { |
425 #if defined(OS_ANDROID) | 533 #if defined(OS_ANDROID) |
426 if (!must_suspend) | 534 if (!must_suspend) |
427 return false; | 535 return false; |
428 | 536 |
429 if (!paused_) { | 537 if (!paused_) { |
430 pause(); | 538 pause(); |
431 should_play_upon_shown_ = true; | 539 should_play_upon_shown_ = true; |
432 } | 540 } |
433 | 541 |
434 if (delegate_) | 542 if (delegate_) |
435 delegate_->PlayerGone(delegate_id_); | 543 delegate_->PlayerGone(delegate_id_); |
436 | 544 |
437 render_frame_suspended_ = true; | 545 frame_deliverer_->SetRenderFrameSuspended(true); |
438 #endif | 546 #endif // defined(OS_ANDROID) |
439 return true; | 547 return true; |
440 } | 548 } |
441 | 549 |
442 void WebMediaPlayerMS::OnPlay() { | 550 void WebMediaPlayerMS::OnPlay() { |
443 // TODO(perkj, magjed): It's not clear how WebRTC should work with an | 551 // TODO(perkj, magjed): It's not clear how WebRTC should work with an |
444 // MediaSession, until these issues are resolved, disable session controls. | 552 // MediaSession, until these issues are resolved, disable session controls. |
445 // http://crbug.com/595297. | 553 // http://crbug.com/595297. |
446 } | 554 } |
447 | 555 |
448 void WebMediaPlayerMS::OnPause() { | 556 void WebMediaPlayerMS::OnPause() { |
(...skipping 26 matching lines...) Expand all Loading... | |
475 // GPU Process crashed. | 583 // GPU Process crashed. |
476 if (!provider) | 584 if (!provider) |
477 return false; | 585 return false; |
478 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); | 586 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); |
479 DCHECK(context_3d.gl); | 587 DCHECK(context_3d.gl); |
480 return video_renderer_.CopyVideoFrameTexturesToGLTexture( | 588 return video_renderer_.CopyVideoFrameTexturesToGLTexture( |
481 context_3d, gl, video_frame.get(), texture, internal_format, type, | 589 context_3d, gl, video_frame.get(), texture, internal_format, type, |
482 premultiply_alpha, flip_y); | 590 premultiply_alpha, flip_y); |
483 } | 591 } |
484 | 592 |
485 void WebMediaPlayerMS::OnFrameAvailable( | 593 void WebMediaPlayerMS::OnFirstFrameReceived(media::VideoRotation video_rotation, |
486 const scoped_refptr<media::VideoFrame>& frame) { | 594 bool is_opaque) { |
487 DVLOG(3) << __func__; | 595 DVLOG(1) << __func__; |
596 DCHECK(thread_checker_.CalledOnValidThread()); | |
597 video_rotation_ = video_rotation; | |
qiangchen
2016/11/09 23:23:48
Is it possible to eliminate video_rotation_? I fou
emircan
2016/11/11 22:27:19
It is also used in WebMediaPlayerMS::naturalSize()
qiangchen
2016/11/15 00:04:54
Acknowledged.
| |
598 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | |
599 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | |
600 | |
601 video_weblayer_.reset(new cc_blink::WebLayerImpl( | |
602 cc::VideoLayer::Create(compositor_.get(), video_rotation_))); | |
603 video_weblayer_->layer()->SetContentsOpaque(is_opaque); | |
604 video_weblayer_->SetContentsOpaqueIsFixed(true); | |
605 get_client()->setWebLayer(video_weblayer_.get()); | |
606 } | |
607 | |
608 void WebMediaPlayerMS::OnOpacityChanged(bool is_opaque) { | |
609 DVLOG(1) << __func__; | |
488 DCHECK(thread_checker_.CalledOnValidThread()); | 610 DCHECK(thread_checker_.CalledOnValidThread()); |
489 | 611 |
490 if (render_frame_suspended_) | 612 video_weblayer_->layer()->SetContentsOpaque(is_opaque); |
491 return; | |
492 | |
493 base::TimeTicks render_time; | |
494 if (frame->metadata()->GetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, | |
495 &render_time)) { | |
496 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable", | |
497 "Ideal Render Instant", render_time.ToInternalValue()); | |
498 } else { | |
499 TRACE_EVENT0("webrtc", "WebMediaPlayerMS::OnFrameAvailable"); | |
500 } | |
501 const bool is_opaque = media::IsOpaque(frame->format()); | |
502 | |
503 if (!received_first_frame_) { | |
504 received_first_frame_ = true; | |
505 last_frame_opaque_ = is_opaque; | |
506 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | |
507 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | |
508 | |
509 if (video_frame_provider_.get()) { | |
510 ignore_result(frame->metadata()->GetRotation( | |
511 media::VideoFrameMetadata::ROTATION, &video_rotation_)); | |
512 | |
513 video_weblayer_.reset(new cc_blink::WebLayerImpl( | |
514 cc::VideoLayer::Create(compositor_.get(), video_rotation_))); | |
515 video_weblayer_->layer()->SetContentsOpaque(is_opaque); | |
516 video_weblayer_->SetContentsOpaqueIsFixed(true); | |
517 get_client()->setWebLayer(video_weblayer_.get()); | |
518 } | |
519 } | |
520 | |
521 // Only configure opacity on changes, since marking it as transparent is | |
522 // expensive, see https://crbug.com/647886. | |
523 if (video_weblayer_ && last_frame_opaque_ != is_opaque) { | |
524 last_frame_opaque_ = is_opaque; | |
525 video_weblayer_->layer()->SetContentsOpaque(is_opaque); | |
526 } | |
527 | |
528 compositor_->EnqueueFrame(frame); | |
529 } | 613 } |
530 | 614 |
531 void WebMediaPlayerMS::RepaintInternal() { | 615 void WebMediaPlayerMS::RepaintInternal() { |
532 DVLOG(1) << __func__; | 616 DVLOG(1) << __func__; |
533 DCHECK(thread_checker_.CalledOnValidThread()); | 617 DCHECK(thread_checker_.CalledOnValidThread()); |
534 get_client()->repaint(); | 618 get_client()->repaint(); |
535 } | 619 } |
536 | 620 |
537 void WebMediaPlayerMS::OnSourceError() { | 621 void WebMediaPlayerMS::OnSourceError() { |
538 DCHECK(thread_checker_.CalledOnValidThread()); | 622 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 22 matching lines...) Expand all Loading... | |
561 void WebMediaPlayerMS::ResetCanvasCache() { | 645 void WebMediaPlayerMS::ResetCanvasCache() { |
562 DCHECK(thread_checker_.CalledOnValidThread()); | 646 DCHECK(thread_checker_.CalledOnValidThread()); |
563 video_renderer_.ResetCache(); | 647 video_renderer_.ResetCache(); |
564 } | 648 } |
565 | 649 |
566 void WebMediaPlayerMS::TriggerResize() { | 650 void WebMediaPlayerMS::TriggerResize() { |
567 get_client()->sizeChanged(); | 651 get_client()->sizeChanged(); |
568 } | 652 } |
569 | 653 |
570 } // namespace content | 654 } // namespace content |
OLD | NEW |