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