Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/glue/webmediaplayer_impl.h" | 5 #include "webkit/glue/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 #include "webkit/glue/media/media_stream_client.h" | 35 #include "webkit/glue/media/media_stream_client.h" |
| 36 #include "webkit/glue/media/video_renderer_impl.h" | 36 #include "webkit/glue/media/video_renderer_impl.h" |
| 37 #include "webkit/glue/media/web_video_renderer.h" | 37 #include "webkit/glue/media/web_video_renderer.h" |
| 38 #include "webkit/glue/webmediaplayer_delegate.h" | 38 #include "webkit/glue/webmediaplayer_delegate.h" |
| 39 #include "webkit/glue/webmediaplayer_proxy.h" | 39 #include "webkit/glue/webmediaplayer_proxy.h" |
| 40 #include "webkit/glue/webvideoframe_impl.h" | 40 #include "webkit/glue/webvideoframe_impl.h" |
| 41 | 41 |
| 42 using WebKit::WebCanvas; | 42 using WebKit::WebCanvas; |
| 43 using WebKit::WebRect; | 43 using WebKit::WebRect; |
| 44 using WebKit::WebSize; | 44 using WebKit::WebSize; |
| 45 using media::NetworkEvent; | |
| 45 using media::PipelineStatus; | 46 using media::PipelineStatus; |
| 46 | 47 |
| 47 namespace { | 48 namespace { |
| 48 | 49 |
| 49 // Amount of extra memory used by each player instance reported to V8. | 50 // Amount of extra memory used by each player instance reported to V8. |
| 50 // It is not exact number -- first, it differs on different platforms, | 51 // It is not exact number -- first, it differs on different platforms, |
| 51 // and second, it is very hard to calculate. Instead, use some arbitrary | 52 // and second, it is very hard to calculate. Instead, use some arbitrary |
| 52 // value that will cause garbage collection from time to time. We don't want | 53 // value that will cause garbage collection from time to time. We don't want |
| 53 // it to happen on every allocation, but don't want 5k players to sit in memory | 54 // it to happen on every allocation, but don't want 5k players to sit in memory |
| 54 // either. Looks that chosen constant achieves both goals, at least for audio | 55 // either. Looks that chosen constant achieves both goals, at least for audio |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 message_loop_factory_(message_loop_factory), | 114 message_loop_factory_(message_loop_factory), |
| 114 paused_(true), | 115 paused_(true), |
| 115 seeking_(false), | 116 seeking_(false), |
| 116 playback_rate_(0.0f), | 117 playback_rate_(0.0f), |
| 117 pending_seek_(false), | 118 pending_seek_(false), |
| 118 client_(client), | 119 client_(client), |
| 119 proxy_(NULL), | 120 proxy_(NULL), |
| 120 delegate_(delegate), | 121 delegate_(delegate), |
| 121 media_stream_client_(media_stream_client), | 122 media_stream_client_(media_stream_client), |
| 122 media_log_(media_log), | 123 media_log_(media_log), |
| 123 incremented_externally_allocated_memory_(false) { | 124 incremented_externally_allocated_memory_(false), |
| 125 can_play_through_(false) { | |
| 124 // Saves the current message loop. | 126 // Saves the current message loop. |
| 125 DCHECK(!main_loop_); | 127 DCHECK(!main_loop_); |
| 126 main_loop_ = MessageLoop::current(); | 128 main_loop_ = MessageLoop::current(); |
| 127 media_log_->AddEvent( | 129 media_log_->AddEvent( |
| 128 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 130 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 129 } | 131 } |
| 130 | 132 |
| 131 bool WebMediaPlayerImpl::Initialize( | 133 bool WebMediaPlayerImpl::Initialize( |
| 132 WebKit::WebFrame* frame, | 134 WebKit::WebFrame* frame, |
| 133 bool use_simple_data_source, | 135 bool use_simple_data_source, |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 pending_seek_ = true; | 337 pending_seek_ = true; |
| 336 pending_seek_seconds_ = seconds; | 338 pending_seek_seconds_ = seconds; |
| 337 return; | 339 return; |
| 338 } | 340 } |
| 339 | 341 |
| 340 media_log_->AddEvent(media_log_->CreateSeekEvent(seconds)); | 342 media_log_->AddEvent(media_log_->CreateSeekEvent(seconds)); |
| 341 | 343 |
| 342 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); | 344 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); |
| 343 | 345 |
| 344 // Update our paused time. | 346 // Update our paused time. |
| 345 if (paused_) { | 347 if (paused_) |
| 346 paused_time_ = seek_time; | 348 paused_time_ = seek_time; |
| 347 } | |
| 348 | 349 |
| 349 seeking_ = true; | 350 seeking_ = true; |
| 350 | 351 |
| 351 proxy_->DemuxerFlush(); | 352 proxy_->DemuxerFlush(); |
| 352 | 353 |
| 353 // Kick off the asynchronous seek! | 354 // Kick off the asynchronous seek! |
| 354 pipeline_->Seek( | 355 pipeline_->Seek( |
| 355 seek_time, | 356 seek_time, |
| 356 base::Bind(&WebMediaPlayerProxy::PipelineSeekCallback, | 357 base::Bind(&WebMediaPlayerProxy::PipelineSeekCallback, |
| 357 proxy_.get())); | 358 proxy_.get())); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 458 DCHECK_EQ(main_loop_, MessageLoop::current()); | 459 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 459 | 460 |
| 460 base::TimeDelta duration = pipeline_->GetMediaDuration(); | 461 base::TimeDelta duration = pipeline_->GetMediaDuration(); |
| 461 if (duration.InMicroseconds() == media::Limits::kMaxTimeInMicroseconds) | 462 if (duration.InMicroseconds() == media::Limits::kMaxTimeInMicroseconds) |
| 462 return std::numeric_limits<float>::infinity(); | 463 return std::numeric_limits<float>::infinity(); |
| 463 return static_cast<float>(duration.InSecondsF()); | 464 return static_cast<float>(duration.InSecondsF()); |
| 464 } | 465 } |
| 465 | 466 |
| 466 float WebMediaPlayerImpl::currentTime() const { | 467 float WebMediaPlayerImpl::currentTime() const { |
| 467 DCHECK_EQ(main_loop_, MessageLoop::current()); | 468 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 468 if (paused_) { | 469 if (paused_) |
| 469 return static_cast<float>(paused_time_.InSecondsF()); | 470 return static_cast<float>(paused_time_.InSecondsF()); |
| 470 } | |
| 471 return static_cast<float>(pipeline_->GetCurrentTime().InSecondsF()); | 471 return static_cast<float>(pipeline_->GetCurrentTime().InSecondsF()); |
| 472 } | 472 } |
| 473 | 473 |
| 474 int WebMediaPlayerImpl::dataRate() const { | 474 int WebMediaPlayerImpl::dataRate() const { |
| 475 DCHECK_EQ(main_loop_, MessageLoop::current()); | 475 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 476 | 476 |
| 477 // TODO(hclam): Add this method call if pipeline has it in the interface. | 477 // TODO(hclam): Add this method call if pipeline has it in the interface. |
| 478 return 0; | 478 return 0; |
| 479 } | 479 } |
| 480 | 480 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 void WebMediaPlayerImpl::OnPipelineInitialize(PipelineStatus status) { | 701 void WebMediaPlayerImpl::OnPipelineInitialize(PipelineStatus status) { |
| 702 DCHECK_EQ(main_loop_, MessageLoop::current()); | 702 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 703 if (status == media::PIPELINE_OK) { | 703 if (status == media::PIPELINE_OK) { |
| 704 // Only keep one time range starting from 0. | 704 // Only keep one time range starting from 0. |
| 705 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); | 705 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); |
| 706 new_buffered[0].start = 0.0f; | 706 new_buffered[0].start = 0.0f; |
| 707 new_buffered[0].end = | 707 new_buffered[0].end = |
| 708 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF()); | 708 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF()); |
| 709 buffered_.swap(new_buffered); | 709 buffered_.swap(new_buffered); |
| 710 | 710 |
| 711 if (pipeline_->IsLoaded()) { | 711 if (pipeline_->IsLoaded()) |
| 712 SetNetworkState(WebKit::WebMediaPlayer::Loaded); | 712 SetNetworkState(WebKit::WebMediaPlayer::Loaded); |
| 713 } | |
| 714 | 713 |
| 715 // Since we have initialized the pipeline, say we have everything otherwise | |
| 716 // we'll remain either loading/idle. | |
| 717 // TODO(hclam): change this to report the correct status. | |
| 718 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata); | 714 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata); |
| 719 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | 715 SetReadyState(WebKit::WebMediaPlayer::HaveFutureData); |
| 720 } else { | 716 } else { |
| 721 // TODO(hclam): should use |status| to determine the state | 717 // TODO(hclam): should use |status| to determine the state |
| 722 // properly and reports error using MediaError. | 718 // properly and reports error using MediaError. |
| 723 // WebKit uses FormatError to indicate an error for bogus URL or bad file. | 719 // WebKit uses FormatError to indicate an error for bogus URL or bad file. |
| 724 // Since we are at the initialization stage we can safely treat every error | 720 // Since we are at the initialization stage we can safely treat every error |
| 725 // as format error. Should post a task to call to |webmediaplayer_|. | 721 // as format error. Should post a task to call to |webmediaplayer_|. |
| 726 SetNetworkState(WebKit::WebMediaPlayer::FormatError); | 722 SetNetworkState(WebKit::WebMediaPlayer::FormatError); |
| 727 } | 723 } |
| 728 | 724 |
| 729 // Repaint to trigger UI update. | 725 // Repaint to trigger UI update. |
| 730 Repaint(); | 726 Repaint(); |
| 731 } | 727 } |
| 732 | 728 |
| 733 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) { | 729 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) { |
| 734 DCHECK_EQ(main_loop_, MessageLoop::current()); | 730 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 735 seeking_ = false; | 731 seeking_ = false; |
| 736 if (pending_seek_) { | 732 if (pending_seek_) { |
| 737 pending_seek_ = false; | 733 pending_seek_ = false; |
| 738 seek(pending_seek_seconds_); | 734 seek(pending_seek_seconds_); |
| 739 return; | 735 return; |
| 740 } | 736 } |
| 741 | 737 |
| 742 if (status == media::PIPELINE_OK) { | 738 if (status == media::PIPELINE_OK) { |
| 743 // Update our paused time. | 739 // Update our paused time. |
| 744 if (paused_) { | 740 if (paused_) |
| 745 paused_time_ = pipeline_->GetCurrentTime(); | 741 paused_time_ = pipeline_->GetCurrentTime(); |
| 746 } | |
| 747 | 742 |
| 748 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | 743 if (!can_play_through_) |
|
acolwell GONE FROM CHROMIUM
2011/11/09 00:50:22
I just want to double check what is going on here.
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
Talked in person. It appears I can get get rid of
| |
| 744 SetReadyState(WebKit::WebMediaPlayer::HaveFutureData); | |
| 745 else | |
| 746 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | |
| 747 | |
| 749 GetClient()->timeChanged(); | 748 GetClient()->timeChanged(); |
| 750 } | 749 } |
| 751 } | 750 } |
| 752 | 751 |
| 753 void WebMediaPlayerImpl::OnPipelineEnded(PipelineStatus status) { | 752 void WebMediaPlayerImpl::OnPipelineEnded(PipelineStatus status) { |
| 754 DCHECK_EQ(main_loop_, MessageLoop::current()); | 753 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 755 if (status == media::PIPELINE_OK) { | 754 if (status == media::PIPELINE_OK) |
| 756 GetClient()->timeChanged(); | 755 GetClient()->timeChanged(); |
| 757 } | |
| 758 } | 756 } |
| 759 | 757 |
| 760 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { | 758 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { |
| 761 DCHECK_EQ(main_loop_, MessageLoop::current()); | 759 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 762 switch (error) { | 760 switch (error) { |
| 763 case media::PIPELINE_OK: | 761 case media::PIPELINE_OK: |
| 764 LOG(DFATAL) << "PIPELINE_OK isn't an error!"; | 762 LOG(DFATAL) << "PIPELINE_OK isn't an error!"; |
| 765 break; | 763 break; |
| 766 | 764 |
| 767 case media::PIPELINE_ERROR_NETWORK: | 765 case media::PIPELINE_ERROR_NETWORK: |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 791 case media::PIPELINE_ERROR_INVALID_STATE: | 789 case media::PIPELINE_ERROR_INVALID_STATE: |
| 792 // Decode error. | 790 // Decode error. |
| 793 SetNetworkState(WebMediaPlayer::DecodeError); | 791 SetNetworkState(WebMediaPlayer::DecodeError); |
| 794 break; | 792 break; |
| 795 } | 793 } |
| 796 | 794 |
| 797 // Repaint to trigger UI update. | 795 // Repaint to trigger UI update. |
| 798 Repaint(); | 796 Repaint(); |
| 799 } | 797 } |
| 800 | 798 |
| 801 void WebMediaPlayerImpl::OnNetworkEvent(bool is_downloading_data) { | 799 void WebMediaPlayerImpl::OnNetworkEvent(NetworkEvent type) { |
| 802 DCHECK_EQ(main_loop_, MessageLoop::current()); | 800 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 803 if (is_downloading_data) | 801 switch(type) { |
| 804 SetNetworkState(WebKit::WebMediaPlayer::Loading); | 802 case media::DOWNLOAD_CONTINUED: |
| 805 else | 803 SetNetworkState(WebKit::WebMediaPlayer::Loading); |
| 806 SetNetworkState(WebKit::WebMediaPlayer::Idle); | 804 break; |
| 805 case media::DOWNLOAD_PAUSED: | |
| 806 SetNetworkState(WebKit::WebMediaPlayer::Idle); | |
| 807 break; | |
| 808 case media::CAN_PLAY_THROUGH: | |
| 809 if (!can_play_through_) { | |
|
acolwell GONE FROM CHROMIUM
2011/11/09 00:50:22
Do we really only want to do this once or is it ok
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
For now, I think we really only want to do this on
| |
| 810 can_play_through_ = true; | |
|
scherkus (not reviewing)
2011/11/09 02:55:15
so if we determine that our connection is "good en
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
Yes. It's not necessarily a good assumption, but I
| |
| 811 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | |
| 812 } | |
| 813 break; | |
| 814 default: | |
| 815 NOTREACHED(); | |
| 816 } | |
| 807 } | 817 } |
| 808 | 818 |
| 809 void WebMediaPlayerImpl::OnDemuxerOpened() { | 819 void WebMediaPlayerImpl::OnDemuxerOpened() { |
| 810 DCHECK_EQ(main_loop_, MessageLoop::current()); | 820 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 811 | 821 |
| 812 GetClient()->sourceOpened(); | 822 GetClient()->sourceOpened(); |
| 813 } | 823 } |
| 814 | 824 |
| 815 void WebMediaPlayerImpl::SetNetworkState( | 825 void WebMediaPlayerImpl::SetNetworkState( |
| 816 WebKit::WebMediaPlayer::NetworkState state) { | 826 WebKit::WebMediaPlayer::NetworkState state) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 868 return client_; | 878 return client_; |
| 869 } | 879 } |
| 870 | 880 |
| 871 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 881 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
| 872 DCHECK_EQ(main_loop_, MessageLoop::current()); | 882 DCHECK_EQ(main_loop_, MessageLoop::current()); |
| 873 incremented_externally_allocated_memory_ = true; | 883 incremented_externally_allocated_memory_ = true; |
| 874 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 884 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |
| 875 } | 885 } |
| 876 | 886 |
| 877 } // namespace webkit_glue | 887 } // namespace webkit_glue |
| OLD | NEW |