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

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

Issue 1265433003: Preliminary change for new rtc rendering algorithm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use Compositor Thread to Start/Stop Rendering Created 5 years, 4 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 <limits> 7 #include <limits>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "cc/blink/context_provider_web_context.h" 13 #include "cc/blink/context_provider_web_context.h"
14 #include "cc/blink/web_layer_impl.h" 14 #include "cc/blink/web_layer_impl.h"
15 #include "cc/layers/video_frame_provider_client_impl.h"
15 #include "cc/layers/video_layer.h" 16 #include "cc/layers/video_layer.h"
16 #include "content/public/renderer/media_stream_audio_renderer.h" 17 #include "content/public/renderer/media_stream_audio_renderer.h"
17 #include "content/public/renderer/media_stream_renderer_factory.h" 18 #include "content/public/renderer/media_stream_renderer_factory.h"
18 #include "content/public/renderer/render_view.h" 19 #include "content/public/renderer/render_view.h"
19 #include "content/public/renderer/video_frame_provider.h" 20 #include "content/public/renderer/video_frame_provider.h"
20 #include "content/renderer/render_frame_impl.h" 21 #include "content/renderer/render_frame_impl.h"
21 #include "content/renderer/render_thread_impl.h" 22 #include "content/renderer/render_thread_impl.h"
22 #include "gpu/blink/webgraphicscontext3d_impl.h" 23 #include "gpu/blink/webgraphicscontext3d_impl.h"
23 #include "media/base/media_log.h" 24 #include "media/base/media_log.h"
24 #include "media/base/video_frame.h" 25 #include "media/base/video_frame.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 return new_frame; 87 return new_frame;
87 } 88 }
88 89
89 } // anonymous namespace 90 } // anonymous namespace
90 91
91 WebMediaPlayerMS::WebMediaPlayerMS( 92 WebMediaPlayerMS::WebMediaPlayerMS(
92 blink::WebFrame* frame, 93 blink::WebFrame* frame,
93 blink::WebMediaPlayerClient* client, 94 blink::WebMediaPlayerClient* client,
94 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, 95 base::WeakPtr<media::WebMediaPlayerDelegate> delegate,
95 media::MediaLog* media_log, 96 media::MediaLog* media_log,
96 scoped_ptr<MediaStreamRendererFactory> factory) 97 scoped_ptr<MediaStreamRendererFactory> factory,
98 scoped_refptr<base::SingleThreadTaskRunner> compositor_thread)
97 : frame_(frame), 99 : frame_(frame),
98 network_state_(WebMediaPlayer::NetworkStateEmpty), 100 network_state_(WebMediaPlayer::NetworkStateEmpty),
99 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), 101 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
100 buffered_(static_cast<size_t>(0)), 102 buffered_(static_cast<size_t>(0)),
101 volume_(1.0f), 103 volume_(1.0f),
102 client_(client), 104 client_(client),
103 delegate_(delegate), 105 delegate_(delegate),
104 paused_(true), 106 paused_(true),
105 current_frame_used_(false), 107 current_frame_used_(false),
106 video_frame_provider_client_(NULL), 108 video_frame_provider_client_(NULL),
107 received_first_frame_(false), 109 received_first_frame_(false),
108 total_frame_count_(0), 110 total_frame_count_(0),
109 dropped_frame_count_(0), 111 dropped_frame_count_(0),
110 media_log_(media_log), 112 media_log_(media_log),
111 renderer_factory_(factory.Pass()) { 113 renderer_factory_(factory.Pass()),
114 compositor_thread_(compositor_thread),
115 wait_event_(false,false) {
112 DVLOG(1) << "WebMediaPlayerMS::ctor"; 116 DVLOG(1) << "WebMediaPlayerMS::ctor";
113 media_log_->AddEvent( 117 media_log_->AddEvent(
114 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 118 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
115 } 119 }
116 120
117 WebMediaPlayerMS::~WebMediaPlayerMS() { 121 WebMediaPlayerMS::~WebMediaPlayerMS() {
118 DVLOG(1) << "WebMediaPlayerMS::dtor"; 122 DVLOG(1) << "WebMediaPlayerMS::dtor";
119 DCHECK(thread_checker_.CalledOnValidThread()); 123 DCHECK(thread_checker_.CalledOnValidThread());
120 124
121 SetVideoFrameProviderClient(NULL); 125 // Wait till stop procedure finishes to avoid the case that after
126 // WebMediaPlayerMS is destroyed, VideoFrameProvider is still trying to access
127 // it.
128
129 if (video_frame_provider_client_){
130 compositor_thread_->PostTask(
131 FROM_HERE,
132 base::Bind(
133 &WebMediaPlayerMS::StopVideoFrameProviderAndWakeUpHelper,
134 video_frame_provider_client_,
135 &wait_event_));
136 wait_event_.Wait();
DaleCurtis 2015/08/13 18:06:53 Hmm, this is unfortunate. Typically you'd use Comp
qiangchen 2015/08/14 16:52:50 Done.
137 }
138
122 GetClient()->setWebLayer(NULL); 139 GetClient()->setWebLayer(NULL);
123 140
124 if (video_frame_provider_.get()) 141 if (video_frame_provider_.get())
125 video_frame_provider_->Stop(); 142 video_frame_provider_->Stop();
126 143
127 if (audio_renderer_.get()) 144 if (audio_renderer_.get())
128 audio_renderer_->Stop(); 145 audio_renderer_->Stop();
129 146
130 media_log_->AddEvent( 147 media_log_->AddEvent(
131 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); 148 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 197 }
181 198
182 void WebMediaPlayerMS::play() { 199 void WebMediaPlayerMS::play() {
183 DVLOG(1) << "WebMediaPlayerMS::play"; 200 DVLOG(1) << "WebMediaPlayerMS::play";
184 DCHECK(thread_checker_.CalledOnValidThread()); 201 DCHECK(thread_checker_.CalledOnValidThread());
185 202
186 if (paused_) { 203 if (paused_) {
187 if (video_frame_provider_.get()) 204 if (video_frame_provider_.get())
188 video_frame_provider_->Play(); 205 video_frame_provider_->Play();
189 206
207 if (video_frame_provider_client_){
208 compositor_thread_->PostTask(
209 FROM_HERE,
210 base::Bind(&WebMediaPlayerMS::StartRenderingHelper,
211 video_frame_provider_client_));
212 }
213
190 if (audio_renderer_.get()) 214 if (audio_renderer_.get())
191 audio_renderer_->Play(); 215 audio_renderer_->Play();
192 216
193 if (delegate_.get()) 217 if (delegate_.get())
194 delegate_->DidPlay(this); 218 delegate_->DidPlay(this);
195 } 219 }
196 220
197 paused_ = false; 221 paused_ = false;
198 222
199 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); 223 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
200 } 224 }
201 225
202 void WebMediaPlayerMS::pause() { 226 void WebMediaPlayerMS::pause() {
203 DVLOG(1) << "WebMediaPlayerMS::pause"; 227 DVLOG(1) << "WebMediaPlayerMS::pause";
204 DCHECK(thread_checker_.CalledOnValidThread()); 228 DCHECK(thread_checker_.CalledOnValidThread());
205 229
206 if (video_frame_provider_.get()) 230 if (video_frame_provider_.get())
207 video_frame_provider_->Pause(); 231 video_frame_provider_->Pause();
208 232
233 if (video_frame_provider_client_){
234 compositor_thread_->PostTask(
235 FROM_HERE,
236 base::Bind(&WebMediaPlayerMS::StopRenderingHelper,
237 video_frame_provider_client_));
238 }
239
209 if (!paused_) { 240 if (!paused_) {
210 if (audio_renderer_.get()) 241 if (audio_renderer_.get())
211 audio_renderer_->Pause(); 242 audio_renderer_->Pause();
212 243
213 if (delegate_.get()) 244 if (delegate_.get())
214 delegate_->DidPause(this); 245 delegate_->DidPause(this);
215 } 246 }
216 247
217 paused_ = true; 248 paused_ = true;
218 249
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 gl, video_frame.get(), texture, internal_format, type, premultiply_alpha, 473 gl, video_frame.get(), texture, internal_format, type, premultiply_alpha,
443 flip_y); 474 flip_y);
444 return true; 475 return true;
445 } 476 }
446 477
447 void WebMediaPlayerMS::SetVideoFrameProviderClient( 478 void WebMediaPlayerMS::SetVideoFrameProviderClient(
448 cc::VideoFrameProvider::Client* client) { 479 cc::VideoFrameProvider::Client* client) {
449 // This is called from both the main renderer thread and the compositor 480 // This is called from both the main renderer thread and the compositor
450 // thread (when the main thread is blocked). 481 // thread (when the main thread is blocked).
451 if (video_frame_provider_client_) 482 if (video_frame_provider_client_)
452 video_frame_provider_client_->StopUsingProvider(); 483 compositor_thread_->PostTask(
484 FROM_HERE,
485 base::Bind(
486 &WebMediaPlayerMS::StopVideoFrameProviderHelper,
487 video_frame_provider_client_));
488
453 video_frame_provider_client_ = client; 489 video_frame_provider_client_ = client;
490 if (client && !paused_)
491 compositor_thread_->PostTask(
492 FROM_HERE,
493 base::Bind(&WebMediaPlayerMS::StartRenderingHelper,
494 video_frame_provider_client_));
495 }
496
497 void WebMediaPlayerMS::StopVideoFrameProviderAndWakeUpHelper(
498 cc::VideoFrameProvider::Client* client,
499 base::WaitableEvent* event) {
500 client->StopUsingProvider();
501 event->Signal();
502 }
503
504 void WebMediaPlayerMS::StopVideoFrameProviderHelper(
505 cc::VideoFrameProvider::Client* client) {
506 client->StopUsingProvider();
507 }
508
509 void WebMediaPlayerMS::StartRenderingHelper(
510 cc::VideoFrameProvider::Client* client) {
511 client->StartRendering();
512 }
513
514 void WebMediaPlayerMS::StopRenderingHelper(
515 cc::VideoFrameProvider::Client* client) {
516 client->StopRendering();
454 } 517 }
455 518
456 bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min, 519 bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min,
457 base::TimeTicks deadline_max) { 520 base::TimeTicks deadline_max) {
521 TRACE_EVENT_BEGIN2("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
522 "Actual Render Begin", deadline_min.ToInternalValue(),
523 "Actual Render End", deadline_max.ToInternalValue());
524 last_deadline_max_ = deadline_max;
525
458 // TODO(dalecurtis): This should make use of the deadline interval to ensure 526 // TODO(dalecurtis): This should make use of the deadline interval to ensure
459 // the painted frame is correct for the given interval. 527 // the painted frame is correct for the given interval.
460 NOTREACHED(); 528
461 return false; 529 base::TimeTicks render_time;
530 if (!current_frame_->metadata()->GetTimeTicks(
531 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
532 render_time = base::TimeTicks();
533 }
534 TRACE_EVENT_END1("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
535 "Ideal Render Instant", render_time.ToInternalValue());
536 return !current_frame_used_;
462 } 537 }
463 538
464 bool WebMediaPlayerMS::HasCurrentFrame() { 539 bool WebMediaPlayerMS::HasCurrentFrame() {
465 base::AutoLock auto_lock(current_frame_lock_); 540 base::AutoLock auto_lock(current_frame_lock_);
466 return current_frame_; 541 return current_frame_;
467 } 542 }
468 543
469 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() { 544 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
470 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame"; 545 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
471 base::AutoLock auto_lock(current_frame_lock_); 546 base::AutoLock auto_lock(current_frame_lock_);
472 if (!current_frame_.get()) 547 if (!current_frame_.get())
473 return NULL; 548 return NULL;
474 current_frame_used_ = true; 549 current_frame_used_ = true;
475 return current_frame_; 550 return current_frame_;
476 } 551 }
477 552
478 void WebMediaPlayerMS::PutCurrentFrame() { 553 void WebMediaPlayerMS::PutCurrentFrame() {
479 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame"; 554 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
480 } 555 }
481 556
482 void WebMediaPlayerMS::OnFrameAvailable( 557 void WebMediaPlayerMS::OnFrameAvailable(
483 const scoped_refptr<media::VideoFrame>& frame) { 558 const scoped_refptr<media::VideoFrame>& frame) {
484 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable"; 559 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
485 DCHECK(thread_checker_.CalledOnValidThread()); 560 DCHECK(thread_checker_.CalledOnValidThread());
561
562 base::TimeTicks render_time;
563 if (!frame->metadata()->GetTimeTicks(
564 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
565 render_time = base::TimeTicks();
566 }
567 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable",
568 "Ideal Render Instant", render_time.ToInternalValue());
569
486 ++total_frame_count_; 570 ++total_frame_count_;
487 if (!received_first_frame_) { 571 if (!received_first_frame_) {
488 received_first_frame_ = true; 572 received_first_frame_ = true;
489 { 573 {
490 base::AutoLock auto_lock(current_frame_lock_); 574 base::AutoLock auto_lock(current_frame_lock_);
491 DCHECK(!current_frame_used_); 575 DCHECK(!current_frame_used_);
492 current_frame_ = frame; 576 current_frame_ = frame;
493 } 577 }
494 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); 578 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
495 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 579 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
496 GetClient()->sizeChanged(); 580 GetClient()->sizeChanged();
497 581
498 if (video_frame_provider_.get()) { 582 if (video_frame_provider_.get()) {
499 video_weblayer_.reset(new cc_blink::WebLayerImpl( 583 video_weblayer_.reset(new cc_blink::WebLayerImpl(
500 cc::VideoLayer::Create(cc_blink::WebLayerImpl::LayerSettings(), this, 584 cc::VideoLayer::Create(cc_blink::WebLayerImpl::LayerSettings(), this,
501 media::VIDEO_ROTATION_0))); 585 media::VIDEO_ROTATION_0)));
502 video_weblayer_->setOpaque(true); 586 video_weblayer_->setOpaque(true);
503 GetClient()->setWebLayer(video_weblayer_.get()); 587 GetClient()->setWebLayer(video_weblayer_.get());
504 } 588 }
505 } 589 }
506 590
507 // Do not update |current_frame_| when paused. 591 // Do not update |current_frame_| when paused.
508 if (paused_) 592 if (paused_)
509 return; 593 return;
510 594
595 if (base::TimeTicks::Now() > last_deadline_max_){
596 // TODO(qiangchen): Theoretically Now is between
597 // [last_deadline_min_ - vsync_duration, last_deadline_min]. If Now is later
598 // than last_deadline_max, it means UpdateCurrentFrame does not get called
599 // for 2 vsyncs. A probable cause is that the video tag is invisible, but we
600 // have to let old frames go (VRA::RemoveExpiredFrames), otherwise frames
601 // will pile up, and when we use up all frame buffers, decoder will be
602 // stuck.
603 }
604
511 bool size_changed = !current_frame_.get() || 605 bool size_changed = !current_frame_.get() ||
512 current_frame_->natural_size() != frame->natural_size(); 606 current_frame_->natural_size() != frame->natural_size();
513 607
514 { 608 {
515 base::AutoLock auto_lock(current_frame_lock_); 609 base::AutoLock auto_lock(current_frame_lock_);
516 if (!current_frame_used_ && current_frame_.get()) 610 if (!current_frame_used_ && current_frame_.get())
517 ++dropped_frame_count_; 611 ++dropped_frame_count_;
518 current_frame_ = frame; 612 current_frame_ = frame;
519 current_time_ = frame->timestamp(); 613 current_time_ = frame->timestamp();
520 current_frame_used_ = false; 614 current_frame_used_ = false;
521 } 615 }
522 616
523 if (size_changed) 617 if (size_changed)
524 GetClient()->sizeChanged(); 618 GetClient()->sizeChanged();
525
526 GetClient()->repaint();
527 } 619 }
528 620
529 void WebMediaPlayerMS::RepaintInternal() { 621 void WebMediaPlayerMS::RepaintInternal() {
530 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal"; 622 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
531 DCHECK(thread_checker_.CalledOnValidThread()); 623 DCHECK(thread_checker_.CalledOnValidThread());
532 GetClient()->repaint(); 624 GetClient()->repaint();
533 } 625 }
534 626
535 void WebMediaPlayerMS::OnSourceError() { 627 void WebMediaPlayerMS::OnSourceError() {
536 DVLOG(1) << "WebMediaPlayerMS::OnSourceError"; 628 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
(...skipping 16 matching lines...) Expand all
553 GetClient()->readyStateChanged(); 645 GetClient()->readyStateChanged();
554 } 646 }
555 647
556 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() { 648 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
557 DCHECK(thread_checker_.CalledOnValidThread()); 649 DCHECK(thread_checker_.CalledOnValidThread());
558 DCHECK(client_); 650 DCHECK(client_);
559 return client_; 651 return client_;
560 } 652 }
561 653
562 } // namespace content 654 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webmediaplayer_ms.h ('k') | content/renderer/media/webrtc/media_stream_remote_video_source.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698