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 |