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 "media/blink/webmediaplayer_impl.h" | 5 #include "media/blink/webmediaplayer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <limits> | 9 #include <limits> |
10 #include <string> | 10 #include <string> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/callback.h" | 15 #include "base/callback.h" |
16 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/debug/alias.h" | 18 #include "base/debug/alias.h" |
19 #include "base/debug/crash_logging.h" | 19 #include "base/debug/crash_logging.h" |
20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
21 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
22 #include "base/synchronization/waitable_event.h" | |
23 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
24 #include "base/thread_task_runner_handle.h" | 23 #include "base/thread_task_runner_handle.h" |
25 #include "base/trace_event/trace_event.h" | 24 #include "base/trace_event/trace_event.h" |
26 #include "build/build_config.h" | 25 #include "build/build_config.h" |
27 #include "cc/blink/web_layer_impl.h" | 26 #include "cc/blink/web_layer_impl.h" |
28 #include "cc/layers/video_layer.h" | 27 #include "cc/layers/video_layer.h" |
29 #include "media/audio/null_audio_sink.h" | 28 #include "media/audio/null_audio_sink.h" |
30 #include "media/base/bind_to_current_loop.h" | 29 #include "media/base/bind_to_current_loop.h" |
31 #include "media/base/cdm_context.h" | 30 #include "media/base/cdm_context.h" |
32 #include "media/base/limits.h" | 31 #include "media/base/limits.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 media_task_runner_(params.media_task_runner()), | 157 media_task_runner_(params.media_task_runner()), |
159 worker_task_runner_(params.worker_task_runner()), | 158 worker_task_runner_(params.worker_task_runner()), |
160 media_log_(params.media_log()), | 159 media_log_(params.media_log()), |
161 pipeline_(media_task_runner_, media_log_.get()), | 160 pipeline_(media_task_runner_, media_log_.get()), |
162 pipeline_controller_( | 161 pipeline_controller_( |
163 &pipeline_, | 162 &pipeline_, |
164 base::Bind(&WebMediaPlayerImpl::CreateRenderer, | 163 base::Bind(&WebMediaPlayerImpl::CreateRenderer, |
165 base::Unretained(this)), | 164 base::Unretained(this)), |
166 base::Bind(&WebMediaPlayerImpl::OnPipelineSeeked, AsWeakPtr()), | 165 base::Bind(&WebMediaPlayerImpl::OnPipelineSeeked, AsWeakPtr()), |
167 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), | 166 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), |
168 base::Bind(&WebMediaPlayerImpl::OnPipelineError, AsWeakPtr())), | 167 base::Bind(&WebMediaPlayerImpl::OnError, AsWeakPtr())), |
169 load_type_(LoadTypeURL), | 168 load_type_(LoadTypeURL), |
170 opaque_(false), | 169 opaque_(false), |
171 playback_rate_(0.0), | 170 playback_rate_(0.0), |
172 paused_(true), | 171 paused_(true), |
173 seeking_(false), | 172 seeking_(false), |
174 pending_suspend_resume_cycle_(false), | 173 pending_suspend_resume_cycle_(false), |
175 ended_(false), | 174 ended_(false), |
176 should_notify_time_changed_(false), | 175 should_notify_time_changed_(false), |
177 fullscreen_(false), | 176 fullscreen_(false), |
178 decoder_requires_restart_for_fullscreen_(false), | 177 decoder_requires_restart_for_fullscreen_(false), |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 suppress_destruction_errors_ = true; | 245 suppress_destruction_errors_ = true; |
247 if (data_source_) | 246 if (data_source_) |
248 data_source_->Abort(); | 247 data_source_->Abort(); |
249 if (chunk_demuxer_) { | 248 if (chunk_demuxer_) { |
250 chunk_demuxer_->Shutdown(); | 249 chunk_demuxer_->Shutdown(); |
251 chunk_demuxer_ = nullptr; | 250 chunk_demuxer_ = nullptr; |
252 } | 251 } |
253 | 252 |
254 renderer_factory_.reset(); | 253 renderer_factory_.reset(); |
255 | 254 |
256 // Make sure to kill the pipeline so there's no more media threads running. | 255 // Pipeline must be stopped before it is destroyed. |
257 // Note: stopping the pipeline might block for a long time. | 256 pipeline_.Stop(); |
258 base::WaitableEvent waiter(false, false); | |
259 pipeline_.Stop( | |
260 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&waiter))); | |
261 waiter.Wait(); | |
262 | 257 |
263 if (last_reported_memory_usage_) | 258 if (last_reported_memory_usage_) |
264 adjust_allocated_memory_cb_.Run(-last_reported_memory_usage_); | 259 adjust_allocated_memory_cb_.Run(-last_reported_memory_usage_); |
265 | 260 |
266 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); | 261 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_); |
267 | 262 |
268 media_log_->AddEvent( | 263 media_log_->AddEvent( |
269 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 264 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
270 } | 265 } |
271 | 266 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // 2) For MSE. | 428 // 2) For MSE. |
434 // Because the buffers may have changed between seeks, MSE seeks are | 429 // Because the buffers may have changed between seeks, MSE seeks are |
435 // never elided. | 430 // never elided. |
436 if (paused_ && pipeline_controller_.IsStable() && paused_time_ == time && | 431 if (paused_ && pipeline_controller_.IsStable() && paused_time_ == time && |
437 !chunk_demuxer_) { | 432 !chunk_demuxer_) { |
438 // If the ready state was high enough before, we can indicate that the seek | 433 // If the ready state was high enough before, we can indicate that the seek |
439 // completed just by restoring it. Otherwise we will just wait for the real | 434 // completed just by restoring it. Otherwise we will just wait for the real |
440 // ready state change to eventually happen. | 435 // ready state change to eventually happen. |
441 if (old_state == ReadyStateHaveEnoughData) { | 436 if (old_state == ReadyStateHaveEnoughData) { |
442 main_task_runner_->PostTask( | 437 main_task_runner_->PostTask( |
443 FROM_HERE, | 438 FROM_HERE, base::Bind(&WebMediaPlayerImpl::OnBufferingStateChange, |
444 base::Bind(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged, | 439 AsWeakPtr(), BUFFERING_HAVE_ENOUGH)); |
445 AsWeakPtr(), BUFFERING_HAVE_ENOUGH)); | |
446 } | 440 } |
447 return; | 441 return; |
448 } | 442 } |
449 | 443 |
450 // TODO(sandersd): Ideally we would not clear the idle state if | 444 // TODO(sandersd): Ideally we would not clear the idle state if |
451 // |pipeline_controller_| can elide the seek. | 445 // |pipeline_controller_| can elide the seek. |
452 is_idle_ = false; | 446 is_idle_ = false; |
453 ended_ = false; | 447 ended_ = false; |
454 | 448 |
455 seeking_ = true; | 449 seeking_ = true; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 blink::WebString::fromUTF8(track->language()), | 836 blink::WebString::fromUTF8(track->language()), |
843 /*selected*/ true); | 837 /*selected*/ true); |
844 (void)track_id; | 838 (void)track_id; |
845 } else { | 839 } else { |
846 // Text tracks are not supported through this code path yet. | 840 // Text tracks are not supported through this code path yet. |
847 NOTREACHED(); | 841 NOTREACHED(); |
848 } | 842 } |
849 } | 843 } |
850 } | 844 } |
851 | 845 |
852 void WebMediaPlayerImpl::OnWaitingForDecryptionKey() { | |
853 encrypted_client_->didBlockPlaybackWaitingForKey(); | |
854 | |
855 // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called | |
856 // when a key has been successfully added (e.g. OnSessionKeysChange() with | |
857 // |has_additional_usable_key| = true). http://crbug.com/461903 | |
858 encrypted_client_->didResumePlaybackBlockedForKey(); | |
859 } | |
860 | |
861 void WebMediaPlayerImpl::SetCdm(const CdmAttachedCB& cdm_attached_cb, | 846 void WebMediaPlayerImpl::SetCdm(const CdmAttachedCB& cdm_attached_cb, |
862 CdmContext* cdm_context) { | 847 CdmContext* cdm_context) { |
863 if (!cdm_context) { | 848 if (!cdm_context) { |
864 cdm_attached_cb.Run(false); | 849 cdm_attached_cb.Run(false); |
865 return; | 850 return; |
866 } | 851 } |
867 | 852 |
868 // If CDM initialization succeeded, tell the pipeline about it. | 853 // If CDM initialization succeeded, tell the pipeline about it. |
869 pipeline_.SetCdm(cdm_context, cdm_attached_cb); | 854 pipeline_.SetCdm(cdm_context, cdm_attached_cb); |
870 } | 855 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 } | 904 } |
920 | 905 |
921 ReportMemoryUsage(); | 906 ReportMemoryUsage(); |
922 | 907 |
923 if (pending_suspend_resume_cycle_) { | 908 if (pending_suspend_resume_cycle_) { |
924 pending_suspend_resume_cycle_ = false; | 909 pending_suspend_resume_cycle_ = false; |
925 UpdatePlayState(); | 910 UpdatePlayState(); |
926 } | 911 } |
927 } | 912 } |
928 | 913 |
929 void WebMediaPlayerImpl::OnPipelineEnded() { | 914 void WebMediaPlayerImpl::OnDemuxerOpened() { |
| 915 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 916 client_->mediaSourceOpened( |
| 917 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); |
| 918 } |
| 919 |
| 920 void WebMediaPlayerImpl::OnError(PipelineStatus status) { |
| 921 DVLOG(1) << __FUNCTION__; |
| 922 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 923 DCHECK_NE(status, PIPELINE_OK); |
| 924 |
| 925 if (suppress_destruction_errors_) |
| 926 return; |
| 927 |
| 928 ReportPipelineError(load_type_, frame_->getSecurityOrigin(), status); |
| 929 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(status)); |
| 930 |
| 931 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { |
| 932 // Any error that occurs before reaching ReadyStateHaveMetadata should |
| 933 // be considered a format error. |
| 934 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
| 935 } else { |
| 936 SetNetworkState(PipelineErrorToNetworkState(status)); |
| 937 } |
| 938 |
| 939 UpdatePlayState(); |
| 940 } |
| 941 |
| 942 void WebMediaPlayerImpl::OnEnded() { |
930 DVLOG(1) << __FUNCTION__; | 943 DVLOG(1) << __FUNCTION__; |
931 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 944 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
932 | 945 |
933 // Ignore state changes until we've completed all outstanding operations. | 946 // Ignore state changes until we've completed all outstanding operations. |
934 if (!pipeline_controller_.IsStable()) | 947 if (!pipeline_controller_.IsStable()) |
935 return; | 948 return; |
936 | 949 |
937 ended_ = true; | 950 ended_ = true; |
938 client_->timeChanged(); | 951 client_->timeChanged(); |
939 | 952 |
940 // We don't actually want this to run until |client_| calls seek() or pause(), | 953 // We don't actually want this to run until |client_| calls seek() or pause(), |
941 // but that should have already happened in timeChanged() and so this is | 954 // but that should have already happened in timeChanged() and so this is |
942 // expected to be a no-op. | 955 // expected to be a no-op. |
943 UpdatePlayState(); | 956 UpdatePlayState(); |
944 } | 957 } |
945 | 958 |
946 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { | 959 void WebMediaPlayerImpl::OnMetadata(PipelineMetadata metadata) { |
947 DVLOG(1) << __FUNCTION__; | 960 DVLOG(1) << __FUNCTION__; |
948 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 961 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
949 DCHECK_NE(error, PIPELINE_OK); | |
950 | |
951 if (suppress_destruction_errors_) | |
952 return; | |
953 | |
954 ReportPipelineError(load_type_, frame_->getSecurityOrigin(), error); | |
955 | |
956 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); | |
957 | |
958 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { | |
959 // Any error that occurs before reaching ReadyStateHaveMetadata should | |
960 // be considered a format error. | |
961 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | |
962 } else { | |
963 SetNetworkState(PipelineErrorToNetworkState(error)); | |
964 } | |
965 | |
966 UpdatePlayState(); | |
967 } | |
968 | |
969 void WebMediaPlayerImpl::OnPipelineMetadata( | |
970 PipelineMetadata metadata) { | |
971 DVLOG(1) << __FUNCTION__; | |
972 | 962 |
973 pipeline_metadata_ = metadata; | 963 pipeline_metadata_ = metadata; |
974 | 964 |
975 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation", metadata.video_rotation, | 965 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation", metadata.video_rotation, |
976 VIDEO_ROTATION_MAX + 1); | 966 VIDEO_ROTATION_MAX + 1); |
977 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 967 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
978 | 968 |
979 if (hasVideo()) { | 969 if (hasVideo()) { |
980 DCHECK(!video_weblayer_); | 970 DCHECK(!video_weblayer_); |
981 scoped_refptr<cc::VideoLayer> layer = | 971 scoped_refptr<cc::VideoLayer> layer = |
982 cc::VideoLayer::Create(compositor_, pipeline_metadata_.video_rotation); | 972 cc::VideoLayer::Create(compositor_, pipeline_metadata_.video_rotation); |
983 | 973 |
984 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || | 974 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || |
985 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { | 975 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { |
986 gfx::Size size = pipeline_metadata_.natural_size; | 976 gfx::Size size = pipeline_metadata_.natural_size; |
987 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); | 977 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); |
988 } | 978 } |
989 | 979 |
990 video_weblayer_.reset(new cc_blink::WebLayerImpl(layer)); | 980 video_weblayer_.reset(new cc_blink::WebLayerImpl(layer)); |
991 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 981 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
992 video_weblayer_->SetContentsOpaqueIsFixed(true); | 982 video_weblayer_->SetContentsOpaqueIsFixed(true); |
993 client_->setWebLayer(video_weblayer_.get()); | 983 client_->setWebLayer(video_weblayer_.get()); |
994 } | 984 } |
995 | 985 |
996 UpdatePlayState(); | 986 UpdatePlayState(); |
997 } | 987 } |
998 | 988 |
999 void WebMediaPlayerImpl::OnPipelineBufferingStateChanged( | 989 void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { |
1000 BufferingState buffering_state) { | 990 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
1001 DVLOG(1) << __FUNCTION__ << "(" << buffering_state << ")"; | 991 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1002 | 992 |
1003 // Ignore buffering state changes until we've completed all outstanding | 993 // Ignore buffering state changes until we've completed all outstanding |
1004 // operations. | 994 // operations. |
1005 if (!pipeline_controller_.IsStable()) | 995 if (!pipeline_controller_.IsStable()) |
1006 return; | 996 return; |
1007 | 997 |
1008 // TODO(scherkus): Handle other buffering states when Pipeline starts using | 998 // TODO(scherkus): Handle other buffering states when Pipeline starts using |
1009 // them and translate them ready state changes http://crbug.com/144683 | 999 // them and translate them ready state changes http://crbug.com/144683 |
1010 DCHECK_EQ(buffering_state, BUFFERING_HAVE_ENOUGH); | 1000 DCHECK_EQ(state, BUFFERING_HAVE_ENOUGH); |
1011 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 1001 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
1012 | 1002 |
1013 // Let the DataSource know we have enough data. It may use this information to | 1003 // Let the DataSource know we have enough data. It may use this information to |
1014 // release unused network connections. | 1004 // release unused network connections. |
1015 if (data_source_) | 1005 if (data_source_) |
1016 data_source_->OnBufferingHaveEnough(false); | 1006 data_source_->OnBufferingHaveEnough(false); |
1017 | 1007 |
1018 // Blink expects a timeChanged() in response to a seek(). | 1008 // Blink expects a timeChanged() in response to a seek(). |
1019 if (should_notify_time_changed_) | 1009 if (should_notify_time_changed_) |
1020 client_->timeChanged(); | 1010 client_->timeChanged(); |
1021 | 1011 |
1022 // Once we have enough, start reporting the total memory usage. We'll also | 1012 // Once we have enough, start reporting the total memory usage. We'll also |
1023 // report once playback starts. | 1013 // report once playback starts. |
1024 ReportMemoryUsage(); | 1014 ReportMemoryUsage(); |
1025 | 1015 |
1026 UpdatePlayState(); | 1016 UpdatePlayState(); |
1027 } | 1017 } |
1028 | 1018 |
1029 void WebMediaPlayerImpl::OnDemuxerOpened() { | 1019 void WebMediaPlayerImpl::OnDurationChange() { |
1030 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1020 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1031 client_->mediaSourceOpened( | 1021 |
1032 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); | 1022 // TODO(sandersd): We should call delegate_->DidPlay() with the new duration, |
| 1023 // especially if it changed from <5s to >5s. |
| 1024 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
| 1025 return; |
| 1026 |
| 1027 client_->durationChanged(); |
1033 } | 1028 } |
1034 | 1029 |
1035 void WebMediaPlayerImpl::OnAddTextTrack( | 1030 void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config, |
1036 const TextTrackConfig& config, | 1031 const AddTextTrackDoneCB& done_cb) { |
1037 const AddTextTrackDoneCB& done_cb) { | |
1038 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1032 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1039 | 1033 |
1040 const WebInbandTextTrackImpl::Kind web_kind = | 1034 const WebInbandTextTrackImpl::Kind web_kind = |
1041 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); | 1035 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); |
1042 const blink::WebString web_label = | 1036 const blink::WebString web_label = |
1043 blink::WebString::fromUTF8(config.label()); | 1037 blink::WebString::fromUTF8(config.label()); |
1044 const blink::WebString web_language = | 1038 const blink::WebString web_language = |
1045 blink::WebString::fromUTF8(config.language()); | 1039 blink::WebString::fromUTF8(config.language()); |
1046 const blink::WebString web_id = | 1040 const blink::WebString web_id = |
1047 blink::WebString::fromUTF8(config.id()); | 1041 blink::WebString::fromUTF8(config.id()); |
1048 | 1042 |
1049 std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track( | 1043 std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track( |
1050 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id)); | 1044 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id)); |
1051 | 1045 |
1052 std::unique_ptr<media::TextTrack> text_track(new TextTrackImpl( | 1046 std::unique_ptr<media::TextTrack> text_track(new TextTrackImpl( |
1053 main_task_runner_, client_, std::move(web_inband_text_track))); | 1047 main_task_runner_, client_, std::move(web_inband_text_track))); |
1054 | 1048 |
1055 done_cb.Run(std::move(text_track)); | 1049 done_cb.Run(std::move(text_track)); |
1056 } | 1050 } |
1057 | 1051 |
| 1052 void WebMediaPlayerImpl::OnWaitingForDecryptionKey() { |
| 1053 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1054 |
| 1055 encrypted_client_->didBlockPlaybackWaitingForKey(); |
| 1056 // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called |
| 1057 // when a key has been successfully added (e.g. OnSessionKeysChange() with |
| 1058 // |has_additional_usable_key| = true). http://crbug.com/461903 |
| 1059 encrypted_client_->didResumePlaybackBlockedForKey(); |
| 1060 } |
| 1061 |
1058 void WebMediaPlayerImpl::OnHidden() { | 1062 void WebMediaPlayerImpl::OnHidden() { |
1059 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1063 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1060 UpdatePlayState(); | 1064 UpdatePlayState(); |
1061 } | 1065 } |
1062 | 1066 |
1063 void WebMediaPlayerImpl::OnShown() { | 1067 void WebMediaPlayerImpl::OnShown() { |
1064 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1068 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1065 must_suspend_ = false; | 1069 must_suspend_ = false; |
1066 UpdatePlayState(); | 1070 UpdatePlayState(); |
1067 } | 1071 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 DCHECK(data_source_); | 1247 DCHECK(data_source_); |
1244 | 1248 |
1245 #if !defined(MEDIA_DISABLE_FFMPEG) | 1249 #if !defined(MEDIA_DISABLE_FFMPEG) |
1246 Demuxer::MediaTracksUpdatedCB media_tracks_updated_cb = | 1250 Demuxer::MediaTracksUpdatedCB media_tracks_updated_cb = |
1247 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated); | 1251 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated); |
1248 | 1252 |
1249 demuxer_.reset(new FFmpegDemuxer(media_task_runner_, data_source_.get(), | 1253 demuxer_.reset(new FFmpegDemuxer(media_task_runner_, data_source_.get(), |
1250 encrypted_media_init_data_cb, | 1254 encrypted_media_init_data_cb, |
1251 media_tracks_updated_cb, media_log_)); | 1255 media_tracks_updated_cb, media_log_)); |
1252 #else | 1256 #else |
1253 OnPipelineError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN); | 1257 OnError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN); |
1254 return; | 1258 return; |
1255 #endif | 1259 #endif |
1256 } else { | 1260 } else { |
1257 DCHECK(!chunk_demuxer_); | 1261 DCHECK(!chunk_demuxer_); |
1258 DCHECK(!data_source_); | 1262 DCHECK(!data_source_); |
1259 | 1263 |
1260 chunk_demuxer_ = new ChunkDemuxer( | 1264 chunk_demuxer_ = new ChunkDemuxer( |
1261 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), | 1265 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), |
1262 encrypted_media_init_data_cb, media_log_, true); | 1266 encrypted_media_init_data_cb, media_log_, true); |
1263 demuxer_.reset(chunk_demuxer_); | 1267 demuxer_.reset(chunk_demuxer_); |
1264 } | 1268 } |
1265 | 1269 |
1266 // TODO(sandersd): FileSystem objects may also be non-static, but due to our | 1270 // TODO(sandersd): FileSystem objects may also be non-static, but due to our |
1267 // caching layer such situations are broken already. http://crbug.com/593159 | 1271 // caching layer such situations are broken already. http://crbug.com/593159 |
1268 bool is_static = !chunk_demuxer_; | 1272 bool is_static = !chunk_demuxer_; |
1269 | 1273 |
1270 // ... and we're ready to go! | 1274 // ... and we're ready to go! |
1271 seeking_ = true; | 1275 seeking_ = true; |
1272 | 1276 |
1273 // TODO(sandersd): On Android, defer Start() if the tab is not visible. | 1277 // TODO(sandersd): On Android, defer Start() if the tab is not visible. |
1274 bool is_streaming = (data_source_ && data_source_->IsStreaming()); | 1278 bool is_streaming = (data_source_ && data_source_->IsStreaming()); |
1275 pipeline_controller_.Start( | 1279 pipeline_controller_.Start(demuxer_.get(), this, is_streaming, is_static); |
1276 demuxer_.get(), is_streaming, is_static, | |
1277 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | |
1278 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), | |
1279 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), | |
1280 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged), | |
1281 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack), | |
1282 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey)); | |
1283 } | 1280 } |
1284 | 1281 |
1285 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1282 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1286 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 1283 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
1287 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1284 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1288 network_state_ = state; | 1285 network_state_ = state; |
1289 // Always notify to ensure client has the latest value. | 1286 // Always notify to ensure client has the latest value. |
1290 client_->networkStateChanged(); | 1287 client_->networkStateChanged(); |
1291 } | 1288 } |
1292 | 1289 |
(...skipping 21 matching lines...) Expand all Loading... |
1314 base::TimeDelta duration = pipeline_.GetMediaDuration(); | 1311 base::TimeDelta duration = pipeline_.GetMediaDuration(); |
1315 | 1312 |
1316 // Return positive infinity if the resource is unbounded. | 1313 // Return positive infinity if the resource is unbounded. |
1317 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration | 1314 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom-
media-duration |
1318 if (duration == kInfiniteDuration()) | 1315 if (duration == kInfiniteDuration()) |
1319 return std::numeric_limits<double>::infinity(); | 1316 return std::numeric_limits<double>::infinity(); |
1320 | 1317 |
1321 return duration.InSecondsF(); | 1318 return duration.InSecondsF(); |
1322 } | 1319 } |
1323 | 1320 |
1324 void WebMediaPlayerImpl::OnDurationChanged() { | |
1325 // TODO(sandersd): We should call delegate_->DidPlay() with the new duration, | |
1326 // especially if it changed from <5s to >5s. | |
1327 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | |
1328 return; | |
1329 | |
1330 client_->durationChanged(); | |
1331 } | |
1332 | |
1333 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { | 1321 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
1334 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1322 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1335 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1323 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
1336 | 1324 |
1337 if (size == pipeline_metadata_.natural_size) | 1325 if (size == pipeline_metadata_.natural_size) |
1338 return; | 1326 return; |
1339 | 1327 |
1340 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 1328 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
1341 media_log_->AddEvent( | 1329 media_log_->AddEvent( |
1342 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 1330 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1584 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
1597 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1585 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
1598 << ", Demuxer: " << demuxer_memory_usage; | 1586 << ", Demuxer: " << demuxer_memory_usage; |
1599 | 1587 |
1600 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1588 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
1601 last_reported_memory_usage_ = current_memory_usage; | 1589 last_reported_memory_usage_ = current_memory_usage; |
1602 adjust_allocated_memory_cb_.Run(delta); | 1590 adjust_allocated_memory_cb_.Run(delta); |
1603 } | 1591 } |
1604 | 1592 |
1605 } // namespace media | 1593 } // namespace media |
OLD | NEW |