Chromium Code Reviews| 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 // FrameDeliverer is responsible for delivering frames received on | |
| 42 // compositor thread by calling of EnqueueFrame() method of |compositor_|. | |
| 43 // | |
| 44 // It is created on the main thread, but methods should be called and class | |
| 45 // should be destructed on the compositor thread. | |
| 46 class WebMediaPlayerMS::FrameDeliverer { | |
| 47 public: | |
| 48 typedef base::Callback<void(scoped_refptr<media::VideoFrame>)> | |
| 49 EnqueueFrameCallback; | |
| 50 | |
| 51 FrameDeliverer(const base::WeakPtr<WebMediaPlayerMS>& player, | |
| 52 const EnqueueFrameCallback& enqueue_frame_cb) | |
| 53 : last_frame_opaque_(true), | |
| 54 received_first_frame_(false), | |
| 55 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
| 56 player_(player), | |
| 57 enqueue_frame_cb_(enqueue_frame_cb), | |
| 58 weak_factory_for_compositor_(this) { | |
| 59 compositor_thread_checker_.DetachFromThread(); | |
| 60 } | |
| 61 | |
| 62 ~FrameDeliverer() { | |
| 63 DCHECK(compositor_thread_checker_.CalledOnValidThread()); | |
| 64 } | |
| 65 | |
| 66 void OnVideoFrame(scoped_refptr<media::VideoFrame> frame) { | |
| 67 DCHECK(compositor_thread_checker_.CalledOnValidThread()); | |
| 68 | |
| 69 #if defined(OS_ANDROID) | |
| 70 if (render_frame_suspended_) | |
| 71 return; | |
| 72 #endif // defined(OS_ANDROID) | |
| 73 | |
| 74 base::TimeTicks render_time; | |
| 75 if (frame->metadata()->GetTimeTicks( | |
| 76 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { | |
| 77 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable", | |
| 78 "Ideal Render Instant", render_time.ToInternalValue()); | |
| 79 } else { | |
| 80 TRACE_EVENT0("webrtc", "WebMediaPlayerMS::OnFrameAvailable"); | |
| 81 } | |
| 82 const bool is_opaque = media::IsOpaque(frame->format()); | |
| 83 | |
| 84 if (!received_first_frame_) { | |
| 85 received_first_frame_ = true; | |
| 86 last_frame_opaque_ = is_opaque; | |
| 87 media::VideoRotation video_rotation; | |
|
Lei Zhang
2016/11/19 06:21:07
This is not initialized and is triggering bug http
| |
| 88 ignore_result(frame->metadata()->GetRotation( | |
| 89 media::VideoFrameMetadata::ROTATION, &video_rotation)); | |
| 90 main_task_runner_->PostTask( | |
| 91 FROM_HERE, base::Bind(&WebMediaPlayerMS::OnFirstFrameReceived, | |
| 92 player_, video_rotation, is_opaque)); | |
| 93 } | |
| 94 | |
| 95 if (last_frame_opaque_ != is_opaque) { | |
| 96 last_frame_opaque_ = is_opaque; | |
| 97 main_task_runner_->PostTask( | |
| 98 FROM_HERE, | |
| 99 base::Bind(&WebMediaPlayerMS::OnOpacityChanged, player_, is_opaque)); | |
| 100 } | |
| 101 | |
| 102 enqueue_frame_cb_.Run(frame); | |
| 103 } | |
| 104 | |
| 105 #if defined(OS_ANDROID) | |
| 106 void SetRenderFrameSuspended(bool render_frame_suspended) { | |
| 107 DCHECK(compositor_thread_checker_.CalledOnValidThread()); | |
| 108 render_frame_suspended_ = render_frame_suspended; | |
| 109 } | |
| 110 #endif // defined(OS_ANDROID) | |
| 111 | |
| 112 MediaStreamVideoRenderer::RepaintCB GetRepaintCallback() { | |
| 113 return base::Bind(&FrameDeliverer::OnVideoFrame, | |
| 114 weak_factory_for_compositor_.GetWeakPtr()); | |
| 115 } | |
| 116 | |
| 117 private: | |
| 118 bool last_frame_opaque_; | |
| 119 bool received_first_frame_; | |
| 120 | |
| 121 #if defined(OS_ANDROID) | |
| 122 bool render_frame_suspended_ = false; | |
| 123 #endif // defined(OS_ANDROID) | |
| 124 | |
| 125 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; | |
| 126 const base::WeakPtr<WebMediaPlayerMS> player_; | |
| 127 const EnqueueFrameCallback enqueue_frame_cb_; | |
| 128 | |
| 129 // Used for DCHECKs to ensure method calls executed on the correct thread, | |
| 130 // i.e. compositor thread. | |
| 131 base::ThreadChecker compositor_thread_checker_; | |
| 132 | |
| 133 base::WeakPtrFactory<FrameDeliverer> weak_factory_for_compositor_; | |
| 134 | |
| 135 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); | |
| 136 }; | |
| 137 | |
| 39 WebMediaPlayerMS::WebMediaPlayerMS( | 138 WebMediaPlayerMS::WebMediaPlayerMS( |
| 40 blink::WebFrame* frame, | 139 blink::WebFrame* frame, |
| 41 blink::WebMediaPlayerClient* client, | 140 blink::WebMediaPlayerClient* client, |
| 42 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, | 141 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, |
| 43 media::MediaLog* media_log, | 142 media::MediaLog* media_log, |
| 44 std::unique_ptr<MediaStreamRendererFactory> factory, | 143 std::unique_ptr<MediaStreamRendererFactory> factory, |
| 45 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, | 144 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, |
| 46 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, | 145 const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
| 47 const scoped_refptr<base::TaskRunner>& worker_task_runner, | 146 const scoped_refptr<base::TaskRunner>& worker_task_runner, |
| 48 media::GpuVideoAcceleratorFactories* gpu_factories, | 147 media::GpuVideoAcceleratorFactories* gpu_factories, |
| 49 const blink::WebString& sink_id, | 148 const blink::WebString& sink_id, |
| 50 const blink::WebSecurityOrigin& security_origin) | 149 const blink::WebSecurityOrigin& security_origin) |
| 51 : frame_(frame), | 150 : frame_(frame), |
| 52 network_state_(WebMediaPlayer::NetworkStateEmpty), | 151 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 53 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 152 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 54 buffered_(static_cast<size_t>(0)), | 153 buffered_(static_cast<size_t>(0)), |
| 55 client_(client), | 154 client_(client), |
| 56 delegate_(delegate), | 155 delegate_(delegate), |
| 57 delegate_id_(0), | 156 delegate_id_(0), |
| 58 last_frame_opaque_(true), | |
| 59 paused_(true), | 157 paused_(true), |
| 60 render_frame_suspended_(false), | |
| 61 received_first_frame_(false), | |
| 62 video_rotation_(media::VIDEO_ROTATION_0), | 158 video_rotation_(media::VIDEO_ROTATION_0), |
| 63 media_log_(media_log), | 159 media_log_(media_log), |
| 64 renderer_factory_(std::move(factory)), | 160 renderer_factory_(std::move(factory)), |
| 65 media_task_runner_(media_task_runner), | 161 media_task_runner_(media_task_runner), |
| 66 worker_task_runner_(worker_task_runner), | 162 worker_task_runner_(worker_task_runner), |
| 67 gpu_factories_(gpu_factories), | 163 gpu_factories_(gpu_factories), |
| 68 compositor_task_runner_(compositor_task_runner), | 164 compositor_task_runner_(compositor_task_runner), |
| 69 initial_audio_output_device_id_(sink_id.utf8()), | 165 initial_audio_output_device_id_(sink_id.utf8()), |
| 70 initial_security_origin_(security_origin.isNull() | 166 initial_security_origin_(security_origin.isNull() |
| 71 ? url::Origin() | 167 ? url::Origin() |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 83 } | 179 } |
| 84 | 180 |
| 85 WebMediaPlayerMS::~WebMediaPlayerMS() { | 181 WebMediaPlayerMS::~WebMediaPlayerMS() { |
| 86 DVLOG(1) << __func__; | 182 DVLOG(1) << __func__; |
| 87 DCHECK(thread_checker_.CalledOnValidThread()); | 183 DCHECK(thread_checker_.CalledOnValidThread()); |
| 88 | 184 |
| 89 // Destruct compositor resources in the proper order. | 185 // Destruct compositor resources in the proper order. |
| 90 get_client()->setWebLayer(nullptr); | 186 get_client()->setWebLayer(nullptr); |
| 91 if (video_weblayer_) | 187 if (video_weblayer_) |
| 92 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); | 188 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); |
| 189 | |
| 190 if (frame_deliverer_) | |
| 191 compositor_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release()); | |
| 192 | |
| 93 if (compositor_) | 193 if (compositor_) |
| 94 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release()); | 194 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release()); |
| 95 | 195 |
| 96 if (video_frame_provider_) | 196 if (video_frame_provider_) |
| 97 video_frame_provider_->Stop(); | 197 video_frame_provider_->Stop(); |
| 98 | 198 |
| 99 if (audio_renderer_) | 199 if (audio_renderer_) |
| 100 audio_renderer_->Stop(); | 200 audio_renderer_->Stop(); |
| 101 | 201 |
| 102 media_log_->AddEvent( | 202 media_log_->AddEvent( |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 122 | 222 |
| 123 compositor_.reset(new WebMediaPlayerMSCompositor(compositor_task_runner_, | 223 compositor_.reset(new WebMediaPlayerMSCompositor(compositor_task_runner_, |
| 124 web_stream, AsWeakPtr())); | 224 web_stream, AsWeakPtr())); |
| 125 | 225 |
| 126 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 226 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
| 127 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); | 227 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); |
| 128 std::string stream_id = | 228 std::string stream_id = |
| 129 web_stream.isNull() ? std::string() : web_stream.id().utf8(); | 229 web_stream.isNull() ? std::string() : web_stream.id().utf8(); |
| 130 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); | 230 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); |
| 131 | 231 |
| 232 // base::Unretained usage is safe here because |compositor_| is destroyed | |
| 233 // after |frame_deliverer_|. | |
| 234 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer( | |
| 235 AsWeakPtr(), base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, | |
| 236 base::Unretained(compositor_.get())))); | |
| 132 video_frame_provider_ = renderer_factory_->GetVideoRenderer( | 237 video_frame_provider_ = renderer_factory_->GetVideoRenderer( |
| 133 web_stream, base::Bind(&WebMediaPlayerMS::OnSourceError, AsWeakPtr()), | 238 web_stream, media::BindToCurrentLoop(base::Bind( |
| 134 base::Bind(&WebMediaPlayerMS::OnFrameAvailable, AsWeakPtr()), | 239 &WebMediaPlayerMS::OnSourceError, AsWeakPtr())), |
| 240 frame_deliverer_->GetRepaintCallback(), compositor_task_runner_, | |
| 135 media_task_runner_, worker_task_runner_, gpu_factories_); | 241 media_task_runner_, worker_task_runner_, gpu_factories_); |
| 136 | 242 |
| 137 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); | 243 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); |
| 138 | 244 |
| 139 if (frame) { | 245 if (frame) { |
| 140 // Report UMA and RAPPOR metrics. | 246 // Report UMA and RAPPOR metrics. |
| 141 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL(); | 247 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL(); |
| 142 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin()); | 248 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin()); |
| 143 | 249 |
| 144 audio_renderer_ = renderer_factory_->GetAudioRenderer( | 250 audio_renderer_ = renderer_factory_->GetAudioRenderer( |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 void WebMediaPlayerMS::OnHidden() { | 501 void WebMediaPlayerMS::OnHidden() { |
| 396 #if defined(OS_ANDROID) | 502 #if defined(OS_ANDROID) |
| 397 DCHECK(thread_checker_.CalledOnValidThread()); | 503 DCHECK(thread_checker_.CalledOnValidThread()); |
| 398 | 504 |
| 399 // Method called when the RenderFrame is sent to background and suspended | 505 // Method called when the RenderFrame is sent to background and suspended |
| 400 // (android). Substitute the displayed VideoFrame with a copy to avoid | 506 // (android). Substitute the displayed VideoFrame with a copy to avoid |
| 401 // holding on to it unnecessarily. | 507 // holding on to it unnecessarily. |
| 402 // | 508 // |
| 403 // During undoable tab closures OnHidden() may be called back to back, so we | 509 // During undoable tab closures OnHidden() may be called back to back, so we |
| 404 // can't rely on |render_frame_suspended_| being false here. | 510 // can't rely on |render_frame_suspended_| being false here. |
| 511 if (frame_deliverer_) { | |
| 512 compositor_task_runner_->PostTask( | |
| 513 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, | |
| 514 base::Unretained(frame_deliverer_.get()), true)); | |
| 515 } | |
| 405 | 516 |
| 406 render_frame_suspended_ = true; | |
| 407 if (!paused_) | 517 if (!paused_) |
| 408 compositor_->ReplaceCurrentFrameWithACopy(); | 518 compositor_->ReplaceCurrentFrameWithACopy(); |
| 409 #endif // defined(OS_ANDROID) | 519 #endif // defined(OS_ANDROID) |
| 410 } | 520 } |
| 411 | 521 |
| 412 void WebMediaPlayerMS::OnShown() { | 522 void WebMediaPlayerMS::OnShown() { |
| 413 #if defined(OS_ANDROID) | 523 #if defined(OS_ANDROID) |
| 414 DCHECK(thread_checker_.CalledOnValidThread()); | 524 DCHECK(thread_checker_.CalledOnValidThread()); |
| 415 | 525 |
| 416 render_frame_suspended_ = false; | 526 if (frame_deliverer_) { |
| 527 compositor_task_runner_->PostTask( | |
| 528 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, | |
| 529 base::Unretained(frame_deliverer_.get()), false)); | |
| 530 } | |
| 417 | 531 |
| 418 // Resume playback on visibility. play() clears |should_play_upon_shown_|. | 532 // Resume playback on visibility. play() clears |should_play_upon_shown_|. |
| 419 if (should_play_upon_shown_) | 533 if (should_play_upon_shown_) |
| 420 play(); | 534 play(); |
| 421 #endif // defined(OS_ANDROID) | 535 #endif // defined(OS_ANDROID) |
| 422 } | 536 } |
| 423 | 537 |
| 424 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) { | 538 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) { |
| 425 #if defined(OS_ANDROID) | 539 #if defined(OS_ANDROID) |
| 426 if (!must_suspend) | 540 if (!must_suspend) |
| 427 return false; | 541 return false; |
| 428 | 542 |
| 429 if (!paused_) { | 543 if (!paused_) { |
| 430 pause(); | 544 pause(); |
| 431 should_play_upon_shown_ = true; | 545 should_play_upon_shown_ = true; |
| 432 } | 546 } |
| 433 | 547 |
| 434 if (delegate_) | 548 if (delegate_) |
| 435 delegate_->PlayerGone(delegate_id_); | 549 delegate_->PlayerGone(delegate_id_); |
| 436 | 550 |
| 437 render_frame_suspended_ = true; | 551 if (frame_deliverer_) { |
| 438 #endif | 552 compositor_task_runner_->PostTask( |
| 553 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, | |
| 554 base::Unretained(frame_deliverer_.get()), true)); | |
| 555 } | |
| 556 #endif // defined(OS_ANDROID) | |
| 439 return true; | 557 return true; |
| 440 } | 558 } |
| 441 | 559 |
| 442 void WebMediaPlayerMS::OnPlay() { | 560 void WebMediaPlayerMS::OnPlay() { |
| 443 // TODO(perkj, magjed): It's not clear how WebRTC should work with an | 561 // TODO(perkj, magjed): It's not clear how WebRTC should work with an |
| 444 // MediaSession, until these issues are resolved, disable session controls. | 562 // MediaSession, until these issues are resolved, disable session controls. |
| 445 // http://crbug.com/595297. | 563 // http://crbug.com/595297. |
| 446 } | 564 } |
| 447 | 565 |
| 448 void WebMediaPlayerMS::OnPause() { | 566 void WebMediaPlayerMS::OnPause() { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 475 // GPU Process crashed. | 593 // GPU Process crashed. |
| 476 if (!provider) | 594 if (!provider) |
| 477 return false; | 595 return false; |
| 478 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); | 596 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); |
| 479 DCHECK(context_3d.gl); | 597 DCHECK(context_3d.gl); |
| 480 return video_renderer_.CopyVideoFrameTexturesToGLTexture( | 598 return video_renderer_.CopyVideoFrameTexturesToGLTexture( |
| 481 context_3d, gl, video_frame.get(), texture, internal_format, type, | 599 context_3d, gl, video_frame.get(), texture, internal_format, type, |
| 482 premultiply_alpha, flip_y); | 600 premultiply_alpha, flip_y); |
| 483 } | 601 } |
| 484 | 602 |
| 485 void WebMediaPlayerMS::OnFrameAvailable( | 603 void WebMediaPlayerMS::OnFirstFrameReceived(media::VideoRotation video_rotation, |
| 486 const scoped_refptr<media::VideoFrame>& frame) { | 604 bool is_opaque) { |
| 487 DVLOG(3) << __func__; | 605 DVLOG(1) << __func__; |
| 606 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 607 video_rotation_ = video_rotation; | |
| 608 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | |
| 609 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | |
| 610 | |
| 611 video_weblayer_.reset(new cc_blink::WebLayerImpl( | |
| 612 cc::VideoLayer::Create(compositor_.get(), video_rotation_))); | |
| 613 video_weblayer_->layer()->SetContentsOpaque(is_opaque); | |
| 614 video_weblayer_->SetContentsOpaqueIsFixed(true); | |
| 615 get_client()->setWebLayer(video_weblayer_.get()); | |
| 616 } | |
| 617 | |
| 618 void WebMediaPlayerMS::OnOpacityChanged(bool is_opaque) { | |
| 619 DVLOG(1) << __func__; | |
| 488 DCHECK(thread_checker_.CalledOnValidThread()); | 620 DCHECK(thread_checker_.CalledOnValidThread()); |
| 489 | 621 |
| 490 if (render_frame_suspended_) | 622 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( | |
|
Lei Zhang
2016/11/19 06:21:07
The previous code was calling GetRotation() on |vi
| |
| 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 } | 623 } |
| 530 | 624 |
| 531 void WebMediaPlayerMS::RepaintInternal() { | 625 void WebMediaPlayerMS::RepaintInternal() { |
| 532 DVLOG(1) << __func__; | 626 DVLOG(1) << __func__; |
| 533 DCHECK(thread_checker_.CalledOnValidThread()); | 627 DCHECK(thread_checker_.CalledOnValidThread()); |
| 534 get_client()->repaint(); | 628 get_client()->repaint(); |
| 535 } | 629 } |
| 536 | 630 |
| 537 void WebMediaPlayerMS::OnSourceError() { | 631 void WebMediaPlayerMS::OnSourceError() { |
| 538 DCHECK(thread_checker_.CalledOnValidThread()); | 632 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 561 void WebMediaPlayerMS::ResetCanvasCache() { | 655 void WebMediaPlayerMS::ResetCanvasCache() { |
| 562 DCHECK(thread_checker_.CalledOnValidThread()); | 656 DCHECK(thread_checker_.CalledOnValidThread()); |
| 563 video_renderer_.ResetCache(); | 657 video_renderer_.ResetCache(); |
| 564 } | 658 } |
| 565 | 659 |
| 566 void WebMediaPlayerMS::TriggerResize() { | 660 void WebMediaPlayerMS::TriggerResize() { |
| 567 get_client()->sizeChanged(); | 661 get_client()->sizeChanged(); |
| 568 } | 662 } |
| 569 | 663 |
| 570 } // namespace content | 664 } // namespace content |
| OLD | NEW |