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

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

Issue 1306203002: Preliminary change for new rtc rendering algorithm (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use .get() to get raw value of the pointer 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 return new_frame; 86 return new_frame;
86 } 87 }
87 88
88 } // anonymous namespace 89 } // anonymous namespace
89 90
90 WebMediaPlayerMS::WebMediaPlayerMS( 91 WebMediaPlayerMS::WebMediaPlayerMS(
91 blink::WebFrame* frame, 92 blink::WebFrame* frame,
92 blink::WebMediaPlayerClient* client, 93 blink::WebMediaPlayerClient* client,
93 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, 94 base::WeakPtr<media::WebMediaPlayerDelegate> delegate,
94 media::MediaLog* media_log, 95 media::MediaLog* media_log,
95 scoped_ptr<MediaStreamRendererFactory> factory) 96 scoped_ptr<MediaStreamRendererFactory> factory,
97 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner)
96 : frame_(frame), 98 : frame_(frame),
97 network_state_(WebMediaPlayer::NetworkStateEmpty), 99 network_state_(WebMediaPlayer::NetworkStateEmpty),
98 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), 100 ready_state_(WebMediaPlayer::ReadyStateHaveNothing),
99 buffered_(static_cast<size_t>(0)), 101 buffered_(static_cast<size_t>(0)),
100 volume_(1.0f), 102 volume_(1.0f),
101 client_(client), 103 client_(client),
102 delegate_(delegate), 104 delegate_(delegate),
103 paused_(true), 105 paused_(true),
104 current_frame_used_(false),
105 video_frame_provider_client_(NULL),
106 received_first_frame_(false), 106 received_first_frame_(false),
107 total_frame_count_(0),
108 dropped_frame_count_(0),
109 media_log_(media_log), 107 media_log_(media_log),
110 renderer_factory_(factory.Pass()) { 108 renderer_factory_(factory.Pass()),
109 compositor_(new Compositor(compositor_task_runner)),
110 compositor_task_runner_(compositor_task_runner) {
111 DVLOG(1) << "WebMediaPlayerMS::ctor"; 111 DVLOG(1) << "WebMediaPlayerMS::ctor";
112 media_log_->AddEvent( 112 media_log_->AddEvent(
113 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); 113 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED));
114 } 114 }
115 115
116 WebMediaPlayerMS::~WebMediaPlayerMS() { 116 WebMediaPlayerMS::~WebMediaPlayerMS() {
117 DVLOG(1) << "WebMediaPlayerMS::dtor"; 117 DVLOG(1) << "WebMediaPlayerMS::dtor";
118 DCHECK(thread_checker_.CalledOnValidThread()); 118 DCHECK(thread_checker_.CalledOnValidThread());
119 119
120 SetVideoFrameProviderClient(NULL); 120 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release());
121
121 GetClient()->setWebLayer(NULL); 122 GetClient()->setWebLayer(NULL);
122 123
123 if (video_frame_provider_.get()) 124 if (video_frame_provider_.get())
124 video_frame_provider_->Stop(); 125 video_frame_provider_->Stop();
125 126
126 if (audio_renderer_.get()) 127 if (audio_renderer_.get())
127 audio_renderer_->Stop(); 128 audio_renderer_->Stop();
128 129
129 media_log_->AddEvent( 130 media_log_->AddEvent(
130 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); 131 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 180 }
180 181
181 void WebMediaPlayerMS::play() { 182 void WebMediaPlayerMS::play() {
182 DVLOG(1) << "WebMediaPlayerMS::play"; 183 DVLOG(1) << "WebMediaPlayerMS::play";
183 DCHECK(thread_checker_.CalledOnValidThread()); 184 DCHECK(thread_checker_.CalledOnValidThread());
184 185
185 if (paused_) { 186 if (paused_) {
186 if (video_frame_provider_.get()) 187 if (video_frame_provider_.get())
187 video_frame_provider_->Play(); 188 video_frame_provider_->Play();
188 189
190 compositor_task_runner_->PostTask(
191 FROM_HERE, base::Bind(&WebMediaPlayerMS::Compositor::StartRendering,
192 base::Unretained(compositor_.get())));
193
189 if (audio_renderer_.get()) 194 if (audio_renderer_.get())
190 audio_renderer_->Play(); 195 audio_renderer_->Play();
191 196
192 if (delegate_.get()) 197 if (delegate_.get())
193 delegate_->DidPlay(this); 198 delegate_->DidPlay(this);
194 } 199 }
195 200
196 paused_ = false; 201 paused_ = false;
197 202
198 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); 203 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY));
199 } 204 }
200 205
201 void WebMediaPlayerMS::pause() { 206 void WebMediaPlayerMS::pause() {
202 DVLOG(1) << "WebMediaPlayerMS::pause"; 207 DVLOG(1) << "WebMediaPlayerMS::pause";
203 DCHECK(thread_checker_.CalledOnValidThread()); 208 DCHECK(thread_checker_.CalledOnValidThread());
204 209
205 if (video_frame_provider_.get()) 210 if (video_frame_provider_.get())
206 video_frame_provider_->Pause(); 211 video_frame_provider_->Pause();
207 212
213 compositor_task_runner_->PostTask(
214 FROM_HERE, base::Bind(&WebMediaPlayerMS::Compositor::StopRendering,
215 base::Unretained(compositor_.get())));
216
208 if (!paused_) { 217 if (!paused_) {
209 if (audio_renderer_.get()) 218 if (audio_renderer_.get())
210 audio_renderer_->Pause(); 219 audio_renderer_->Pause();
211 220
212 if (delegate_.get()) 221 if (delegate_.get())
213 delegate_->DidPause(this); 222 delegate_->DidPause(this);
214 } 223 }
215 224
216 paused_ = true; 225 paused_ = true;
217 226
218 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE)); 227 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE));
219
220 if (!current_frame_.get())
221 return;
222
223 // Copy the frame so that rendering can show the last received frame.
224 // The original frame must not be referenced when the player is paused since
225 // there might be a finite number of available buffers. E.g, video that
226 // originates from a video camera.
227 scoped_refptr<media::VideoFrame> new_frame =
228 CopyFrameToYV12(current_frame_, &video_renderer_);
229
230 base::AutoLock auto_lock(current_frame_lock_);
231 current_frame_ = new_frame;
232 } 228 }
233 229
234 bool WebMediaPlayerMS::supportsSave() const { 230 bool WebMediaPlayerMS::supportsSave() const {
235 DCHECK(thread_checker_.CalledOnValidThread()); 231 DCHECK(thread_checker_.CalledOnValidThread());
236 return false; 232 return false;
237 } 233 }
238 234
239 void WebMediaPlayerMS::seek(double seconds) { 235 void WebMediaPlayerMS::seek(double seconds) {
240 DCHECK(thread_checker_.CalledOnValidThread()); 236 DCHECK(thread_checker_.CalledOnValidThread());
241 } 237 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 277 }
282 278
283 bool WebMediaPlayerMS::hasAudio() const { 279 bool WebMediaPlayerMS::hasAudio() const {
284 DCHECK(thread_checker_.CalledOnValidThread()); 280 DCHECK(thread_checker_.CalledOnValidThread());
285 return (audio_renderer_.get() != NULL); 281 return (audio_renderer_.get() != NULL);
286 } 282 }
287 283
288 blink::WebSize WebMediaPlayerMS::naturalSize() const { 284 blink::WebSize WebMediaPlayerMS::naturalSize() const {
289 DCHECK(thread_checker_.CalledOnValidThread()); 285 DCHECK(thread_checker_.CalledOnValidThread());
290 286
291 gfx::Size size; 287 gfx::Size size = compositor_->GetCurrentSize();
292 if (current_frame_.get()) 288
293 size = current_frame_->natural_size();
294 DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString(); 289 DVLOG(3) << "WebMediaPlayerMS::naturalSize, " << size.ToString();
295 return blink::WebSize(size); 290 return blink::WebSize(size);
296 } 291 }
297 292
298 bool WebMediaPlayerMS::paused() const { 293 bool WebMediaPlayerMS::paused() const {
299 DCHECK(thread_checker_.CalledOnValidThread()); 294 DCHECK(thread_checker_.CalledOnValidThread());
300 return paused_; 295 return paused_;
301 } 296 }
302 297
303 bool WebMediaPlayerMS::seeking() const { 298 bool WebMediaPlayerMS::seeking() const {
304 DCHECK(thread_checker_.CalledOnValidThread()); 299 DCHECK(thread_checker_.CalledOnValidThread());
305 return false; 300 return false;
306 } 301 }
307 302
308 double WebMediaPlayerMS::duration() const { 303 double WebMediaPlayerMS::duration() const {
309 DCHECK(thread_checker_.CalledOnValidThread()); 304 DCHECK(thread_checker_.CalledOnValidThread());
310 return std::numeric_limits<double>::infinity(); 305 return std::numeric_limits<double>::infinity();
311 } 306 }
312 307
313 double WebMediaPlayerMS::currentTime() const { 308 double WebMediaPlayerMS::currentTime() const {
314 DCHECK(thread_checker_.CalledOnValidThread()); 309 DCHECK(thread_checker_.CalledOnValidThread());
315 if (current_time_.ToInternalValue() != 0) { 310 base::TimeDelta current_time = compositor_->GetCurrentTime();
316 return current_time_.InSecondsF(); 311 if (current_time.ToInternalValue() != 0) {
312 return current_time.InSecondsF();
317 } else if (audio_renderer_.get()) { 313 } else if (audio_renderer_.get()) {
318 return audio_renderer_->GetCurrentRenderTime().InSecondsF(); 314 return audio_renderer_->GetCurrentRenderTime().InSecondsF();
319 } 315 }
320 return 0.0; 316 return 0.0;
321 } 317 }
322 318
323 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const { 319 WebMediaPlayer::NetworkState WebMediaPlayerMS::networkState() const {
324 DCHECK(thread_checker_.CalledOnValidThread()); 320 DCHECK(thread_checker_.CalledOnValidThread());
325 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_; 321 DVLOG(1) << "WebMediaPlayerMS::networkState, state:" << network_state_;
326 return network_state_; 322 return network_state_;
(...skipping 20 matching lines...) Expand all
347 return true; 343 return true;
348 } 344 }
349 345
350 void WebMediaPlayerMS::paint(blink::WebCanvas* canvas, 346 void WebMediaPlayerMS::paint(blink::WebCanvas* canvas,
351 const blink::WebRect& rect, 347 const blink::WebRect& rect,
352 unsigned char alpha, 348 unsigned char alpha,
353 SkXfermode::Mode mode) { 349 SkXfermode::Mode mode) {
354 DVLOG(3) << "WebMediaPlayerMS::paint"; 350 DVLOG(3) << "WebMediaPlayerMS::paint";
355 DCHECK(thread_checker_.CalledOnValidThread()); 351 DCHECK(thread_checker_.CalledOnValidThread());
356 352
353 scoped_refptr<media::VideoFrame> frame = compositor_->GetCurrentFrame();
354
357 media::Context3D context_3d; 355 media::Context3D context_3d;
358 if (current_frame_.get() && current_frame_->HasTextures()) { 356 if (frame.get() && frame->HasTextures()) {
359 cc::ContextProvider* provider = 357 cc::ContextProvider* provider =
360 RenderThreadImpl::current()->SharedMainThreadContextProvider().get(); 358 RenderThreadImpl::current()->SharedMainThreadContextProvider().get();
361 // GPU Process crashed. 359 // GPU Process crashed.
362 if (!provider) 360 if (!provider)
363 return; 361 return;
364 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext()); 362 context_3d = media::Context3D(provider->ContextGL(), provider->GrContext());
365 DCHECK(context_3d.gl); 363 DCHECK(context_3d.gl);
366 } 364 }
367 gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height); 365 gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
368 video_renderer_.Paint(current_frame_, canvas, dest_rect, alpha, mode, 366 video_renderer_.Paint(frame, canvas, dest_rect, alpha, mode,
369 media::VIDEO_ROTATION_0, context_3d); 367 media::VIDEO_ROTATION_0, context_3d);
370
371 {
372 base::AutoLock auto_lock(current_frame_lock_);
373 if (current_frame_.get())
374 current_frame_used_ = true;
375 }
376 } 368 }
377 369
378 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const { 370 bool WebMediaPlayerMS::hasSingleSecurityOrigin() const {
379 DCHECK(thread_checker_.CalledOnValidThread()); 371 DCHECK(thread_checker_.CalledOnValidThread());
380 return true; 372 return true;
381 } 373 }
382 374
383 bool WebMediaPlayerMS::didPassCORSAccessCheck() const { 375 bool WebMediaPlayerMS::didPassCORSAccessCheck() const {
384 DCHECK(thread_checker_.CalledOnValidThread()); 376 DCHECK(thread_checker_.CalledOnValidThread());
385 return true; 377 return true;
386 } 378 }
387 379
388 double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const { 380 double WebMediaPlayerMS::mediaTimeForTimeValue(double timeValue) const {
389 return base::TimeDelta::FromSecondsD(timeValue).InSecondsF(); 381 return base::TimeDelta::FromSecondsD(timeValue).InSecondsF();
390 } 382 }
391 383
392 unsigned WebMediaPlayerMS::decodedFrameCount() const { 384 unsigned WebMediaPlayerMS::decodedFrameCount() const {
393 DCHECK(thread_checker_.CalledOnValidThread()); 385 DCHECK(thread_checker_.CalledOnValidThread());
394 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count_; 386 unsigned total_frame_count = compositor_->GetTotalFrameCount();
395 return total_frame_count_; 387 DVLOG(1) << "WebMediaPlayerMS::decodedFrameCount, " << total_frame_count;
388 return total_frame_count;
396 } 389 }
397 390
398 unsigned WebMediaPlayerMS::droppedFrameCount() const { 391 unsigned WebMediaPlayerMS::droppedFrameCount() const {
399 DCHECK(thread_checker_.CalledOnValidThread()); 392 DCHECK(thread_checker_.CalledOnValidThread());
400 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count_; 393 unsigned dropped_frame_count = compositor_->GetDroppedFrameCount();
401 return dropped_frame_count_; 394 DVLOG(1) << "WebMediaPlayerMS::droppedFrameCount, " << dropped_frame_count;
395 return dropped_frame_count;
402 } 396 }
403 397
404 unsigned WebMediaPlayerMS::audioDecodedByteCount() const { 398 unsigned WebMediaPlayerMS::audioDecodedByteCount() const {
405 DCHECK(thread_checker_.CalledOnValidThread()); 399 DCHECK(thread_checker_.CalledOnValidThread());
406 NOTIMPLEMENTED(); 400 NOTIMPLEMENTED();
407 return 0; 401 return 0;
408 } 402 }
409 403
410 unsigned WebMediaPlayerMS::videoDecodedByteCount() const { 404 unsigned WebMediaPlayerMS::videoDecodedByteCount() const {
411 DCHECK(thread_checker_.CalledOnValidThread()); 405 DCHECK(thread_checker_.CalledOnValidThread());
412 NOTIMPLEMENTED(); 406 NOTIMPLEMENTED();
413 return 0; 407 return 0;
414 } 408 }
415 409
416 bool WebMediaPlayerMS::copyVideoTextureToPlatformTexture( 410 bool WebMediaPlayerMS::copyVideoTextureToPlatformTexture(
417 blink::WebGraphicsContext3D* web_graphics_context, 411 blink::WebGraphicsContext3D* web_graphics_context,
418 unsigned int texture, 412 unsigned int texture,
419 unsigned int internal_format, 413 unsigned int internal_format,
420 unsigned int type, 414 unsigned int type,
421 bool premultiply_alpha, 415 bool premultiply_alpha,
422 bool flip_y) { 416 bool flip_y) {
423 TRACE_EVENT0("media", "WebMediaPlayerMS:copyVideoTextureToPlatformTexture"); 417 TRACE_EVENT0("media", "WebMediaPlayerMS:copyVideoTextureToPlatformTexture");
424 DCHECK(thread_checker_.CalledOnValidThread()); 418 DCHECK(thread_checker_.CalledOnValidThread());
425 419
426 scoped_refptr<media::VideoFrame> video_frame; 420 scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame();
427 {
428 base::AutoLock auto_lock(current_frame_lock_);
429 video_frame = current_frame_;
430 }
431 421
432 if (!video_frame.get() || video_frame->HasTextures() || 422 if (!video_frame.get() || video_frame->HasTextures() ||
433 media::VideoFrame::NumPlanes(video_frame->format()) != 1) { 423 media::VideoFrame::NumPlanes(video_frame->format()) != 1) {
434 return false; 424 return false;
435 } 425 }
436 426
437 // TODO(dshwang): need more elegant way to convert WebGraphicsContext3D to 427 // TODO(dshwang): need more elegant way to convert WebGraphicsContext3D to
438 // GLES2Interface. 428 // GLES2Interface.
439 gpu::gles2::GLES2Interface* gl = 429 gpu::gles2::GLES2Interface* gl =
440 static_cast<gpu_blink::WebGraphicsContext3DImpl*>(web_graphics_context) 430 static_cast<gpu_blink::WebGraphicsContext3DImpl*>(web_graphics_context)
441 ->GetGLInterface(); 431 ->GetGLInterface();
442 media::SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( 432 media::SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
443 gl, video_frame.get(), texture, internal_format, type, premultiply_alpha, 433 gl, video_frame.get(), texture, internal_format, type, premultiply_alpha,
444 flip_y); 434 flip_y);
445 return true; 435 return true;
446 } 436 }
447 437
448 void WebMediaPlayerMS::SetVideoFrameProviderClient(
449 cc::VideoFrameProvider::Client* client) {
450 // This is called from both the main renderer thread and the compositor
451 // thread (when the main thread is blocked).
452 if (video_frame_provider_client_)
453 video_frame_provider_client_->StopUsingProvider();
454 video_frame_provider_client_ = client;
455 }
456
457 bool WebMediaPlayerMS::UpdateCurrentFrame(base::TimeTicks deadline_min,
458 base::TimeTicks deadline_max) {
459 // TODO(dalecurtis): This should make use of the deadline interval to ensure
460 // the painted frame is correct for the given interval.
461 NOTREACHED();
462 return false;
463 }
464
465 bool WebMediaPlayerMS::HasCurrentFrame() {
466 base::AutoLock auto_lock(current_frame_lock_);
467 return current_frame_;
468 }
469
470 scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
471 DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame";
472 base::AutoLock auto_lock(current_frame_lock_);
473 if (!current_frame_.get())
474 return NULL;
475 current_frame_used_ = true;
476 return current_frame_;
477 }
478
479 void WebMediaPlayerMS::PutCurrentFrame() {
480 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
481 }
482
483 void WebMediaPlayerMS::OnFrameAvailable( 438 void WebMediaPlayerMS::OnFrameAvailable(
484 const scoped_refptr<media::VideoFrame>& frame) { 439 const scoped_refptr<media::VideoFrame>& frame) {
485 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable"; 440 DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable";
486 DCHECK(thread_checker_.CalledOnValidThread()); 441 DCHECK(thread_checker_.CalledOnValidThread());
487 ++total_frame_count_; 442
443 base::TimeTicks render_time;
444 if (!frame->metadata()->GetTimeTicks(
445 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
446 render_time = base::TimeTicks();
447 }
448 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable",
449 "Ideal Render Instant", render_time.ToInternalValue());
450
488 if (!received_first_frame_) { 451 if (!received_first_frame_) {
489 received_first_frame_ = true; 452 received_first_frame_ = true;
490 {
491 base::AutoLock auto_lock(current_frame_lock_);
492 DCHECK(!current_frame_used_);
493 current_frame_ = frame;
494 }
495 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); 453 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata);
496 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); 454 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData);
497 GetClient()->sizeChanged();
498 455
499 if (video_frame_provider_.get()) { 456 if (video_frame_provider_.get()) {
500 video_weblayer_.reset(new cc_blink::WebLayerImpl( 457 video_weblayer_.reset(new cc_blink::WebLayerImpl(
501 cc::VideoLayer::Create(cc_blink::WebLayerImpl::LayerSettings(), this, 458 cc::VideoLayer::Create(cc_blink::WebLayerImpl::LayerSettings(),
502 media::VIDEO_ROTATION_0))); 459 compositor_.get(), media::VIDEO_ROTATION_0)));
503 video_weblayer_->setOpaque(true); 460 video_weblayer_->setOpaque(true);
504 GetClient()->setWebLayer(video_weblayer_.get()); 461 GetClient()->setWebLayer(video_weblayer_.get());
505 } 462 }
506 } 463 }
507 464
508 // Do not update |current_frame_| when paused. 465 bool size_changed = compositor_->GetCurrentSize() != frame->natural_size();
509 if (paused_)
510 return;
511 466
512 bool size_changed = !current_frame_.get() || 467 compositor_->EnqueueFrame(frame);
513 current_frame_->natural_size() != frame->natural_size();
514
515 {
516 base::AutoLock auto_lock(current_frame_lock_);
517 if (!current_frame_used_ && current_frame_.get())
518 ++dropped_frame_count_;
519 current_frame_ = frame;
520 current_time_ = frame->timestamp();
521 current_frame_used_ = false;
522 }
523 468
524 if (size_changed) 469 if (size_changed)
525 GetClient()->sizeChanged(); 470 GetClient()->sizeChanged();
526
527 GetClient()->repaint();
528 } 471 }
529 472
530 void WebMediaPlayerMS::RepaintInternal() { 473 void WebMediaPlayerMS::RepaintInternal() {
531 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal"; 474 DVLOG(1) << "WebMediaPlayerMS::RepaintInternal";
532 DCHECK(thread_checker_.CalledOnValidThread()); 475 DCHECK(thread_checker_.CalledOnValidThread());
533 GetClient()->repaint(); 476 GetClient()->repaint();
534 } 477 }
535 478
536 void WebMediaPlayerMS::OnSourceError() { 479 void WebMediaPlayerMS::OnSourceError() {
537 DVLOG(1) << "WebMediaPlayerMS::OnSourceError"; 480 DVLOG(1) << "WebMediaPlayerMS::OnSourceError";
(...skipping 15 matching lines...) Expand all
553 // Always notify to ensure client has the latest value. 496 // Always notify to ensure client has the latest value.
554 GetClient()->readyStateChanged(); 497 GetClient()->readyStateChanged();
555 } 498 }
556 499
557 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() { 500 blink::WebMediaPlayerClient* WebMediaPlayerMS::GetClient() {
558 DCHECK(thread_checker_.CalledOnValidThread()); 501 DCHECK(thread_checker_.CalledOnValidThread());
559 DCHECK(client_); 502 DCHECK(client_);
560 return client_; 503 return client_;
561 } 504 }
562 505
506 WebMediaPlayerMS::Compositor::Compositor(
507 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner)
508 : compositor_task_runner_(compositor_task_runner),
509 video_frame_provider_client_(NULL),
510 current_frame_used_(false),
511 last_deadline_max_(base::TimeTicks()),
512 total_frame_count_(0),
513 dropped_frame_count_(0),
514 paused_(false) {}
515
516 WebMediaPlayerMS::Compositor::~Compositor() {
517 DCHECK(compositor_task_runner_->BelongsToCurrentThread());
518 if (video_frame_provider_client_)
519 video_frame_provider_client_->StopUsingProvider();
520 }
521
522 void WebMediaPlayerMS::Compositor::EnqueueFrame(
523 scoped_refptr<media::VideoFrame> const& frame) {
524 base::AutoLock auto_lock(current_frame_lock_);
525 ++total_frame_count_;
526
527 if (base::TimeTicks::Now() > last_deadline_max_) {
528 // TODO(qiangchen): This shows vsyncs stops rendering frames. A probable
529 // cause is that the tab is not in the front. But we still have to let
530 // old frames go. Call VRA::RemoveExpiredFrames.
531 current_frame_ = frame;
532 }
533
534 if (staging_frame_.get() != current_frame_.get()) {
535 // This shows the staging_frame_ nevers get updated into current_frame_, and
536 // now we are going to overwrite it. The frame should be counted as dropped.
537 ++dropped_frame_count_;
538 }
539
540 // TODO(qiangchen): Instead of using one variable to hold one frame, use
541 // VideoRendererAlgorithm.
542 staging_frame_ = frame;
543 }
544
545 bool WebMediaPlayerMS::Compositor::UpdateCurrentFrame(
546 base::TimeTicks deadline_min,
547 base::TimeTicks deadline_max) {
548 DCHECK(compositor_task_runner_->BelongsToCurrentThread());
549 base::AutoLock auto_lock(current_frame_lock_);
550 TRACE_EVENT_BEGIN2("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
551 "Actual Render Begin", deadline_min.ToInternalValue(),
552 "Actual Render End", deadline_max.ToInternalValue());
553 last_deadline_max_ = deadline_max;
554
555 // TODO(dalecurtis): This should make use of the deadline interval to ensure
556 // the painted frame is correct for the given interval.
557
558 if (paused_)
559 return false;
560
561 if (current_frame_.get() != staging_frame_.get()) {
562 if (!current_frame_used_)
563 ++dropped_frame_count_;
564 current_frame_ = staging_frame_;
565 current_frame_used_ = false;
566 }
567
568 base::TimeTicks render_time;
569 if (!current_frame_->metadata()->GetTimeTicks(
570 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
571 render_time = base::TimeTicks();
572 }
573 TRACE_EVENT_END1("webrtc", "WebMediaPlayerMS::UpdateCurrentFrame",
574 "Ideal Render Instant", render_time.ToInternalValue());
575 return !current_frame_used_;
576 }
577
578 bool WebMediaPlayerMS::Compositor::HasCurrentFrame() {
579 base::AutoLock auto_lock(current_frame_lock_);
580 return !!current_frame_.get();
581 }
582
583 scoped_refptr<media::VideoFrame>
584 WebMediaPlayerMS::Compositor::GetCurrentFrame() {
585 DVLOG(3) << "WebMediaPlayerMS::Compositor::GetCurrentFrame";
586 base::AutoLock auto_lock(current_frame_lock_);
587 if (!current_frame_.get())
588 return NULL;
589 return current_frame_;
590 }
591
592 void WebMediaPlayerMS::Compositor::PutCurrentFrame() {
593 DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame";
594 current_frame_used_ = true;
595 }
596
597 void WebMediaPlayerMS::Compositor::SetVideoFrameProviderClient(
598 cc::VideoFrameProvider::Client* client) {
599 DCHECK(compositor_task_runner_->BelongsToCurrentThread());
600 if (video_frame_provider_client_)
601 video_frame_provider_client_->StopUsingProvider();
602
603 video_frame_provider_client_ = client;
604 if (video_frame_provider_client_)
605 video_frame_provider_client_->StartRendering();
606 }
607
608 void WebMediaPlayerMS::Compositor::StartRendering() {
609 DCHECK(compositor_task_runner_->BelongsToCurrentThread());
610 paused_ = false;
611 if (video_frame_provider_client_)
612 video_frame_provider_client_->StartRendering();
613 }
614
615 void WebMediaPlayerMS::Compositor::StopRendering() {
616 DCHECK(compositor_task_runner_->BelongsToCurrentThread());
617 paused_ = true;
618 if (video_frame_provider_client_)
619 video_frame_provider_client_->StopRendering();
620
621 base::AutoLock auto_lock(current_frame_lock_);
622 if (!current_frame_.get())
623 return;
624
625 // Copy the frame so that rendering can show the last received frame.
626 // The original frame must not be referenced when the player is paused since
627 // there might be a finite number of available buffers. E.g, video that
628 // originates from a video camera.
629 scoped_refptr<media::VideoFrame> new_frame =
630 CopyFrameToYV12(current_frame_, &video_renderer_);
631
632 current_frame_ = new_frame;
633 }
634
635 gfx::Size WebMediaPlayerMS::Compositor::GetCurrentSize() {
636 base::AutoLock auto_lock(current_frame_lock_);
637 return staging_frame_.get() ? staging_frame_->natural_size() : gfx::Size();
638 }
639
640 base::TimeDelta WebMediaPlayerMS::Compositor::GetCurrentTime() {
641 base::AutoLock auto_lock(current_frame_lock_);
642 return staging_frame_.get() ? staging_frame_->timestamp() : base::TimeDelta();
643 }
644
645 unsigned WebMediaPlayerMS::Compositor::GetTotalFrameCount() {
646 return total_frame_count_;
647 }
648
649 unsigned WebMediaPlayerMS::Compositor::GetDroppedFrameCount() {
650 return dropped_frame_count_;
651 }
563 } // namespace content 652 } // 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