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

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

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