| 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_impl.h" | 5 #include "content/renderer/media/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 client_(client), | 164 client_(client), |
| 165 delegate_(delegate), | 165 delegate_(delegate), |
| 166 defer_load_cb_(params.defer_load_cb()), | 166 defer_load_cb_(params.defer_load_cb()), |
| 167 accelerated_compositing_reported_(false), | 167 accelerated_compositing_reported_(false), |
| 168 incremented_externally_allocated_memory_(false), | 168 incremented_externally_allocated_memory_(false), |
| 169 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), | 169 gpu_factories_(RenderThreadImpl::current()->GetGpuFactories()), |
| 170 is_local_source_(false), | 170 is_local_source_(false), |
| 171 supports_save_(true), | 171 supports_save_(true), |
| 172 starting_(false), | 172 starting_(false), |
| 173 chunk_demuxer_(NULL), | 173 chunk_demuxer_(NULL), |
| 174 // Threaded compositing isn't enabled universally yet. | 174 compositor_( // Threaded compositing isn't enabled universally yet. |
| 175 compositor_task_runner_( | 175 (RenderThreadImpl::current()->compositor_message_loop_proxy() |
| 176 RenderThreadImpl::current()->compositor_message_loop_proxy() | 176 ? RenderThreadImpl::current()->compositor_message_loop_proxy() |
| 177 ? RenderThreadImpl::current()->compositor_message_loop_proxy() | 177 : base::MessageLoopProxy::current()), |
| 178 : base::MessageLoopProxy::current()), | |
| 179 compositor_(new VideoFrameCompositor( | |
| 180 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), | 178 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), |
| 181 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), | 179 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged)), |
| 182 text_track_index_(0), | 180 text_track_index_(0), |
| 183 web_cdm_(NULL) { | 181 web_cdm_(NULL) { |
| 184 media_log_->AddEvent( | 182 media_log_->AddEvent( |
| 185 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 183 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 186 | 184 |
| 187 // |gpu_factories_| requires that its entry points be called on its | 185 // |gpu_factories_| requires that its entry points be called on its |
| 188 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the | 186 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the |
| 189 // factories, require that their message loops are identical. | 187 // factories, require that their message loops are identical. |
| 190 DCHECK(!gpu_factories_ || (gpu_factories_->GetTaskRunner() == media_loop_)); | 188 DCHECK(!gpu_factories_ || (gpu_factories_->GetTaskRunner() == media_loop_)); |
| 191 | 189 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 225 |
| 228 gpu_factories_ = NULL; | 226 gpu_factories_ = NULL; |
| 229 | 227 |
| 230 // Make sure to kill the pipeline so there's no more media threads running. | 228 // Make sure to kill the pipeline so there's no more media threads running. |
| 231 // Note: stopping the pipeline might block for a long time. | 229 // Note: stopping the pipeline might block for a long time. |
| 232 base::WaitableEvent waiter(false, false); | 230 base::WaitableEvent waiter(false, false); |
| 233 pipeline_.Stop( | 231 pipeline_.Stop( |
| 234 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); | 232 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); |
| 235 waiter.Wait(); | 233 waiter.Wait(); |
| 236 | 234 |
| 237 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); | |
| 238 | |
| 239 // Let V8 know we are not using extra resources anymore. | 235 // Let V8 know we are not using extra resources anymore. |
| 240 if (incremented_externally_allocated_memory_) { | 236 if (incremented_externally_allocated_memory_) { |
| 241 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( | 237 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory( |
| 242 -kPlayerExtraMemory); | 238 -kPlayerExtraMemory); |
| 243 incremented_externally_allocated_memory_ = false; | 239 incremented_externally_allocated_memory_ = false; |
| 244 } | 240 } |
| 245 } | 241 } |
| 246 | 242 |
| 247 namespace { | 243 namespace { |
| 248 | 244 |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 UMA_HISTOGRAM_BOOLEAN( | 553 UMA_HISTOGRAM_BOOLEAN( |
| 558 "Media.AcceleratedCompositingActive", | 554 "Media.AcceleratedCompositingActive", |
| 559 frame_->view()->isAcceleratedCompositingActive()); | 555 frame_->view()->isAcceleratedCompositingActive()); |
| 560 } | 556 } |
| 561 | 557 |
| 562 // TODO(scherkus): Clarify paint() API contract to better understand when and | 558 // TODO(scherkus): Clarify paint() API contract to better understand when and |
| 563 // why it's being called. For example, today paint() is called when: | 559 // why it's being called. For example, today paint() is called when: |
| 564 // - We haven't reached HAVE_CURRENT_DATA and need to paint black | 560 // - We haven't reached HAVE_CURRENT_DATA and need to paint black |
| 565 // - We're painting to a canvas | 561 // - We're painting to a canvas |
| 566 // See http://crbug.com/341225 http://crbug.com/342621 for details. | 562 // See http://crbug.com/341225 http://crbug.com/342621 for details. |
| 567 scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame(); | 563 scoped_refptr<media::VideoFrame> video_frame = compositor_.GetCurrentFrame(); |
| 568 | 564 |
| 569 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); | 565 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); |
| 570 gfx::Rect gfx_rect(rect); | 566 gfx::Rect gfx_rect(rect); |
| 571 skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha); | 567 skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha); |
| 572 } | 568 } |
| 573 | 569 |
| 574 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { | 570 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { |
| 575 if (data_source_) | 571 if (data_source_) |
| 576 return data_source_->HasSingleOrigin(); | 572 return data_source_->HasSingleOrigin(); |
| 577 return true; | 573 return true; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 591 DCHECK(main_loop_->BelongsToCurrentThread()); | 587 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 592 | 588 |
| 593 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 589 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 594 return stats.video_frames_decoded; | 590 return stats.video_frames_decoded; |
| 595 } | 591 } |
| 596 | 592 |
| 597 unsigned WebMediaPlayerImpl::droppedFrameCount() const { | 593 unsigned WebMediaPlayerImpl::droppedFrameCount() const { |
| 598 DCHECK(main_loop_->BelongsToCurrentThread()); | 594 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 599 | 595 |
| 600 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 596 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 601 return stats.video_frames_dropped; | 597 |
| 598 unsigned frames_dropped = stats.video_frames_dropped; |
| 599 |
| 600 frames_dropped += const_cast<VideoFrameCompositor&>(compositor_) |
| 601 .GetFramesDroppedBeforeCompositorWasNotified(); |
| 602 |
| 603 DCHECK_LE(frames_dropped, stats.video_frames_decoded); |
| 604 return frames_dropped; |
| 602 } | 605 } |
| 603 | 606 |
| 604 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { | 607 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { |
| 605 DCHECK(main_loop_->BelongsToCurrentThread()); | 608 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 606 | 609 |
| 607 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 610 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 608 return stats.audio_bytes_decoded; | 611 return stats.audio_bytes_decoded; |
| 609 } | 612 } |
| 610 | 613 |
| 611 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { | 614 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { |
| 612 DCHECK(main_loop_->BelongsToCurrentThread()); | 615 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 613 | 616 |
| 614 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 617 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
| 615 return stats.video_bytes_decoded; | 618 return stats.video_bytes_decoded; |
| 616 } | 619 } |
| 617 | 620 |
| 618 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( | 621 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( |
| 619 blink::WebGraphicsContext3D* web_graphics_context, | 622 blink::WebGraphicsContext3D* web_graphics_context, |
| 620 unsigned int texture, | 623 unsigned int texture, |
| 621 unsigned int level, | 624 unsigned int level, |
| 622 unsigned int internal_format, | 625 unsigned int internal_format, |
| 623 unsigned int type, | 626 unsigned int type, |
| 624 bool premultiply_alpha, | 627 bool premultiply_alpha, |
| 625 bool flip_y) { | 628 bool flip_y) { |
| 626 scoped_refptr<media::VideoFrame> video_frame = compositor_->GetCurrentFrame(); | 629 scoped_refptr<media::VideoFrame> video_frame = compositor_.GetCurrentFrame(); |
| 627 | 630 |
| 628 TRACE_EVENT0("media", "WebMediaPlayerImpl:copyVideoTextureToPlatformTexture"); | 631 TRACE_EVENT0("media", "WebMediaPlayerImpl:copyVideoTextureToPlatformTexture"); |
| 629 | 632 |
| 630 if (!video_frame) | 633 if (!video_frame) |
| 631 return false; | 634 return false; |
| 632 if (video_frame->format() != media::VideoFrame::NATIVE_TEXTURE) | 635 if (video_frame->format() != media::VideoFrame::NATIVE_TEXTURE) |
| 633 return false; | 636 return false; |
| 634 | 637 |
| 635 gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); | 638 gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); |
| 636 if (mailbox_holder->texture_target != GL_TEXTURE_2D) | 639 if (mailbox_holder->texture_target != GL_TEXTURE_2D) |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 void WebMediaPlayerImpl::OnPipelineMetadata( | 984 void WebMediaPlayerImpl::OnPipelineMetadata( |
| 982 media::PipelineMetadata metadata) { | 985 media::PipelineMetadata metadata) { |
| 983 DVLOG(1) << "OnPipelineMetadata"; | 986 DVLOG(1) << "OnPipelineMetadata"; |
| 984 | 987 |
| 985 pipeline_metadata_ = metadata; | 988 pipeline_metadata_ = metadata; |
| 986 | 989 |
| 987 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 990 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
| 988 | 991 |
| 989 if (hasVideo()) { | 992 if (hasVideo()) { |
| 990 DCHECK(!video_weblayer_); | 993 DCHECK(!video_weblayer_); |
| 991 video_weblayer_.reset( | 994 video_weblayer_.reset(new webkit::WebLayerImpl( |
| 992 new webkit::WebLayerImpl(cc::VideoLayer::Create(compositor_))); | 995 cc::VideoLayer::Create(compositor_.GetVideoFrameProvider()))); |
| 993 video_weblayer_->setOpaque(opaque_); | 996 video_weblayer_->setOpaque(opaque_); |
| 994 client_->setWebLayer(video_weblayer_.get()); | 997 client_->setWebLayer(video_weblayer_.get()); |
| 995 } | 998 } |
| 996 | 999 |
| 997 // TODO(scherkus): This should be handled by HTMLMediaElement and controls | 1000 // TODO(scherkus): This should be handled by HTMLMediaElement and controls |
| 998 // should know when to invalidate themselves http://crbug.com/337015 | 1001 // should know when to invalidate themselves http://crbug.com/337015 |
| 999 InvalidateOnMainThread(); | 1002 InvalidateOnMainThread(); |
| 1000 } | 1003 } |
| 1001 | 1004 |
| 1002 void WebMediaPlayerImpl::OnPipelinePrerollCompleted() { | 1005 void WebMediaPlayerImpl::OnPipelinePrerollCompleted() { |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 DCHECK(main_loop_->BelongsToCurrentThread()); | 1302 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 1300 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1303 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1301 | 1304 |
| 1302 opaque_ = opaque; | 1305 opaque_ = opaque; |
| 1303 if (video_weblayer_) | 1306 if (video_weblayer_) |
| 1304 video_weblayer_->setOpaque(opaque_); | 1307 video_weblayer_->setOpaque(opaque_); |
| 1305 } | 1308 } |
| 1306 | 1309 |
| 1307 void WebMediaPlayerImpl::FrameReady( | 1310 void WebMediaPlayerImpl::FrameReady( |
| 1308 const scoped_refptr<media::VideoFrame>& frame) { | 1311 const scoped_refptr<media::VideoFrame>& frame) { |
| 1309 compositor_task_runner_->PostTask( | 1312 compositor_.UpdateCurrentFrame(frame); |
| 1310 FROM_HERE, | |
| 1311 base::Bind(&VideoFrameCompositor::UpdateCurrentFrame, | |
| 1312 base::Unretained(compositor_), | |
| 1313 frame)); | |
| 1314 } | 1313 } |
| 1315 | 1314 |
| 1316 void WebMediaPlayerImpl::SetDecryptorReadyCB( | 1315 void WebMediaPlayerImpl::SetDecryptorReadyCB( |
| 1317 const media::DecryptorReadyCB& decryptor_ready_cb) { | 1316 const media::DecryptorReadyCB& decryptor_ready_cb) { |
| 1318 DCHECK(main_loop_->BelongsToCurrentThread()); | 1317 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 1319 | 1318 |
| 1320 // Cancels the previous decryptor request. | 1319 // Cancels the previous decryptor request. |
| 1321 if (decryptor_ready_cb.is_null()) { | 1320 if (decryptor_ready_cb.is_null()) { |
| 1322 if (!decryptor_ready_cb_.is_null()) | 1321 if (!decryptor_ready_cb_.is_null()) |
| 1323 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); | 1322 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1341 | 1340 |
| 1342 if (web_cdm_) { | 1341 if (web_cdm_) { |
| 1343 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); | 1342 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); |
| 1344 return; | 1343 return; |
| 1345 } | 1344 } |
| 1346 | 1345 |
| 1347 decryptor_ready_cb_ = decryptor_ready_cb; | 1346 decryptor_ready_cb_ = decryptor_ready_cb; |
| 1348 } | 1347 } |
| 1349 | 1348 |
| 1350 } // namespace content | 1349 } // namespace content |
| OLD | NEW |