| 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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 | 1202 |
| 1206 video_decoders.push_back(new media::FFmpegVideoDecoder(media_loop_)); | 1203 video_decoders.push_back(new media::FFmpegVideoDecoder(media_loop_)); |
| 1207 | 1204 |
| 1208 scoped_ptr<media::VideoRenderer> video_renderer( | 1205 scoped_ptr<media::VideoRenderer> video_renderer( |
| 1209 new media::VideoRendererImpl( | 1206 new media::VideoRendererImpl( |
| 1210 media_loop_, | 1207 media_loop_, |
| 1211 video_decoders.Pass(), | 1208 video_decoders.Pass(), |
| 1212 set_decryptor_ready_cb, | 1209 set_decryptor_ready_cb, |
| 1213 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), | 1210 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), |
| 1214 true)); | 1211 true)); |
| 1212 |
| 1215 filter_collection->SetVideoRenderer(video_renderer.Pass()); | 1213 filter_collection->SetVideoRenderer(video_renderer.Pass()); |
| 1216 | 1214 |
| 1217 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { | 1215 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { |
| 1218 scoped_ptr<media::TextRenderer> text_renderer( | 1216 scoped_ptr<media::TextRenderer> text_renderer( |
| 1219 new media::TextRenderer( | 1217 new media::TextRenderer( |
| 1220 media_loop_, | 1218 media_loop_, |
| 1221 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); | 1219 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); |
| 1222 | 1220 |
| 1223 filter_collection->SetTextRenderer(text_renderer.Pass()); | 1221 filter_collection->SetTextRenderer(text_renderer.Pass()); |
| 1224 } | 1222 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 DCHECK(main_loop_->BelongsToCurrentThread()); | 1300 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 1303 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1301 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1304 | 1302 |
| 1305 opaque_ = opaque; | 1303 opaque_ = opaque; |
| 1306 if (video_weblayer_) | 1304 if (video_weblayer_) |
| 1307 video_weblayer_->setOpaque(opaque_); | 1305 video_weblayer_->setOpaque(opaque_); |
| 1308 } | 1306 } |
| 1309 | 1307 |
| 1310 void WebMediaPlayerImpl::FrameReady( | 1308 void WebMediaPlayerImpl::FrameReady( |
| 1311 const scoped_refptr<media::VideoFrame>& frame) { | 1309 const scoped_refptr<media::VideoFrame>& frame) { |
| 1312 compositor_.UpdateCurrentFrame(frame); | 1310 compositor_task_runner_->PostTask( |
| 1311 FROM_HERE, |
| 1312 base::Bind(&VideoFrameCompositor::UpdateCurrentFrame, |
| 1313 base::Unretained(compositor_), |
| 1314 frame)); |
| 1313 } | 1315 } |
| 1314 | 1316 |
| 1315 void WebMediaPlayerImpl::SetDecryptorReadyCB( | 1317 void WebMediaPlayerImpl::SetDecryptorReadyCB( |
| 1316 const media::DecryptorReadyCB& decryptor_ready_cb) { | 1318 const media::DecryptorReadyCB& decryptor_ready_cb) { |
| 1317 DCHECK(main_loop_->BelongsToCurrentThread()); | 1319 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 1318 | 1320 |
| 1319 // Cancels the previous decryptor request. | 1321 // Cancels the previous decryptor request. |
| 1320 if (decryptor_ready_cb.is_null()) { | 1322 if (decryptor_ready_cb.is_null()) { |
| 1321 if (!decryptor_ready_cb_.is_null()) | 1323 if (!decryptor_ready_cb_.is_null()) |
| 1322 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); | 1324 base::ResetAndReturn(&decryptor_ready_cb_).Run(NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1340 | 1342 |
| 1341 if (web_cdm_) { | 1343 if (web_cdm_) { |
| 1342 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); | 1344 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); |
| 1343 return; | 1345 return; |
| 1344 } | 1346 } |
| 1345 | 1347 |
| 1346 decryptor_ready_cb_ = decryptor_ready_cb; | 1348 decryptor_ready_cb_ = decryptor_ready_cb; |
| 1347 } | 1349 } |
| 1348 | 1350 |
| 1349 } // namespace content | 1351 } // namespace content |
| OLD | NEW |