Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1116)

Side by Side Diff: webkit/glue/webmediaplayer_impl.cc

Issue 8399023: Fire canplaythrough event at the proper time for audio/video (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and minor fix Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698