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. |
xhwang
2016/05/04 06:32:22
nit: Add a note that this is a blocking call.
alokp
2016/05/04 17:40:01
IMO this note would be redundant and confusing. If
| |
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 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(status)); | |
929 | |
930 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { | |
931 // Any error that occurs before reaching ReadyStateHaveMetadata should | |
932 // be considered a format error. | |
933 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | |
934 } else { | |
935 SetNetworkState(PipelineErrorToNetworkState(status)); | |
936 } | |
937 | |
938 UpdatePlayState(); | |
939 } | |
940 | |
941 void WebMediaPlayerImpl::OnEnded() { | |
930 DVLOG(1) << __FUNCTION__; | 942 DVLOG(1) << __FUNCTION__; |
931 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 943 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
932 | 944 |
933 // Ignore state changes until we've completed all outstanding operations. | 945 // Ignore state changes until we've completed all outstanding operations. |
934 if (!pipeline_controller_.IsStable()) | 946 if (!pipeline_controller_.IsStable()) |
935 return; | 947 return; |
936 | 948 |
937 ended_ = true; | 949 ended_ = true; |
938 client_->timeChanged(); | 950 client_->timeChanged(); |
939 | 951 |
940 // We don't actually want this to run until |client_| calls seek() or pause(), | 952 // 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 | 953 // but that should have already happened in timeChanged() and so this is |
942 // expected to be a no-op. | 954 // expected to be a no-op. |
943 UpdatePlayState(); | 955 UpdatePlayState(); |
944 } | 956 } |
945 | 957 |
946 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { | 958 void WebMediaPlayerImpl::OnMetadata(PipelineMetadata metadata) { |
947 DVLOG(1) << __FUNCTION__; | 959 DVLOG(1) << __FUNCTION__; |
948 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 960 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
949 DCHECK_NE(error, PIPELINE_OK); | |
950 | |
951 if (suppress_destruction_errors_) | |
952 return; | |
953 | |
954 media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); | |
955 | |
956 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { | |
957 // Any error that occurs before reaching ReadyStateHaveMetadata should | |
958 // be considered a format error. | |
959 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | |
960 } else { | |
961 SetNetworkState(PipelineErrorToNetworkState(error)); | |
962 } | |
963 | |
964 UpdatePlayState(); | |
965 } | |
966 | |
967 void WebMediaPlayerImpl::OnPipelineMetadata( | |
968 PipelineMetadata metadata) { | |
969 DVLOG(1) << __FUNCTION__; | |
970 | 961 |
971 pipeline_metadata_ = metadata; | 962 pipeline_metadata_ = metadata; |
972 | 963 |
973 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation", metadata.video_rotation, | 964 UMA_HISTOGRAM_ENUMERATION("Media.VideoRotation", metadata.video_rotation, |
974 VIDEO_ROTATION_MAX + 1); | 965 VIDEO_ROTATION_MAX + 1); |
975 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 966 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
976 | 967 |
977 if (hasVideo()) { | 968 if (hasVideo()) { |
978 DCHECK(!video_weblayer_); | 969 DCHECK(!video_weblayer_); |
979 scoped_refptr<cc::VideoLayer> layer = | 970 scoped_refptr<cc::VideoLayer> layer = |
980 cc::VideoLayer::Create(compositor_, pipeline_metadata_.video_rotation); | 971 cc::VideoLayer::Create(compositor_, pipeline_metadata_.video_rotation); |
981 | 972 |
982 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || | 973 if (pipeline_metadata_.video_rotation == VIDEO_ROTATION_90 || |
983 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { | 974 pipeline_metadata_.video_rotation == VIDEO_ROTATION_270) { |
984 gfx::Size size = pipeline_metadata_.natural_size; | 975 gfx::Size size = pipeline_metadata_.natural_size; |
985 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); | 976 pipeline_metadata_.natural_size = gfx::Size(size.height(), size.width()); |
986 } | 977 } |
987 | 978 |
988 video_weblayer_.reset(new cc_blink::WebLayerImpl(layer)); | 979 video_weblayer_.reset(new cc_blink::WebLayerImpl(layer)); |
989 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 980 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
990 video_weblayer_->SetContentsOpaqueIsFixed(true); | 981 video_weblayer_->SetContentsOpaqueIsFixed(true); |
991 client_->setWebLayer(video_weblayer_.get()); | 982 client_->setWebLayer(video_weblayer_.get()); |
992 } | 983 } |
993 | 984 |
994 UpdatePlayState(); | 985 UpdatePlayState(); |
995 } | 986 } |
996 | 987 |
997 void WebMediaPlayerImpl::OnPipelineBufferingStateChanged( | 988 void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { |
998 BufferingState buffering_state) { | 989 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
999 DVLOG(1) << __FUNCTION__ << "(" << buffering_state << ")"; | 990 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1000 | 991 |
1001 // Ignore buffering state changes until we've completed all outstanding | 992 // Ignore buffering state changes until we've completed all outstanding |
1002 // operations. | 993 // operations. |
1003 if (!pipeline_controller_.IsStable()) | 994 if (!pipeline_controller_.IsStable()) |
1004 return; | 995 return; |
1005 | 996 |
1006 // TODO(scherkus): Handle other buffering states when Pipeline starts using | 997 // TODO(scherkus): Handle other buffering states when Pipeline starts using |
1007 // them and translate them ready state changes http://crbug.com/144683 | 998 // them and translate them ready state changes http://crbug.com/144683 |
1008 DCHECK_EQ(buffering_state, BUFFERING_HAVE_ENOUGH); | 999 DCHECK_EQ(state, BUFFERING_HAVE_ENOUGH); |
1009 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 1000 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
1010 | 1001 |
1011 // Let the DataSource know we have enough data. It may use this information to | 1002 // Let the DataSource know we have enough data. It may use this information to |
1012 // release unused network connections. | 1003 // release unused network connections. |
1013 if (data_source_) | 1004 if (data_source_) |
1014 data_source_->OnBufferingHaveEnough(false); | 1005 data_source_->OnBufferingHaveEnough(false); |
1015 | 1006 |
1016 // Blink expects a timeChanged() in response to a seek(). | 1007 // Blink expects a timeChanged() in response to a seek(). |
1017 if (should_notify_time_changed_) | 1008 if (should_notify_time_changed_) |
1018 client_->timeChanged(); | 1009 client_->timeChanged(); |
1019 | 1010 |
1020 // Once we have enough, start reporting the total memory usage. We'll also | 1011 // Once we have enough, start reporting the total memory usage. We'll also |
1021 // report once playback starts. | 1012 // report once playback starts. |
1022 ReportMemoryUsage(); | 1013 ReportMemoryUsage(); |
1023 | 1014 |
1024 UpdatePlayState(); | 1015 UpdatePlayState(); |
1025 } | 1016 } |
1026 | 1017 |
1027 void WebMediaPlayerImpl::OnDemuxerOpened() { | 1018 void WebMediaPlayerImpl::OnDurationChange() { |
1028 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1019 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1029 client_->mediaSourceOpened( | 1020 |
1030 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); | 1021 // TODO(sandersd): We should call delegate_->DidPlay() with the new duration, |
1022 // especially if it changed from <5s to >5s. | |
1023 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | |
1024 return; | |
1025 | |
1026 client_->durationChanged(); | |
1031 } | 1027 } |
1032 | 1028 |
1033 void WebMediaPlayerImpl::OnAddTextTrack( | 1029 void WebMediaPlayerImpl::OnAddTextTrack(const TextTrackConfig& config, |
1034 const TextTrackConfig& config, | 1030 const AddTextTrackDoneCB& done_cb) { |
1035 const AddTextTrackDoneCB& done_cb) { | |
1036 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1031 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1037 | 1032 |
1038 const WebInbandTextTrackImpl::Kind web_kind = | 1033 const WebInbandTextTrackImpl::Kind web_kind = |
1039 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); | 1034 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); |
1040 const blink::WebString web_label = | 1035 const blink::WebString web_label = |
1041 blink::WebString::fromUTF8(config.label()); | 1036 blink::WebString::fromUTF8(config.label()); |
1042 const blink::WebString web_language = | 1037 const blink::WebString web_language = |
1043 blink::WebString::fromUTF8(config.language()); | 1038 blink::WebString::fromUTF8(config.language()); |
1044 const blink::WebString web_id = | 1039 const blink::WebString web_id = |
1045 blink::WebString::fromUTF8(config.id()); | 1040 blink::WebString::fromUTF8(config.id()); |
1046 | 1041 |
1047 std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track( | 1042 std::unique_ptr<WebInbandTextTrackImpl> web_inband_text_track( |
1048 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id)); | 1043 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id)); |
1049 | 1044 |
1050 std::unique_ptr<media::TextTrack> text_track(new TextTrackImpl( | 1045 std::unique_ptr<media::TextTrack> text_track(new TextTrackImpl( |
1051 main_task_runner_, client_, std::move(web_inband_text_track))); | 1046 main_task_runner_, client_, std::move(web_inband_text_track))); |
1052 | 1047 |
1053 done_cb.Run(std::move(text_track)); | 1048 done_cb.Run(std::move(text_track)); |
1054 } | 1049 } |
1055 | 1050 |
1051 void WebMediaPlayerImpl::OnWaitingForDecryptionKey() { | |
1052 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
1053 | |
1054 encrypted_client_->didBlockPlaybackWaitingForKey(); | |
1055 // TODO(jrummell): didResumePlaybackBlockedForKey() should only be called | |
1056 // when a key has been successfully added (e.g. OnSessionKeysChange() with | |
1057 // |has_additional_usable_key| = true). http://crbug.com/461903 | |
1058 encrypted_client_->didResumePlaybackBlockedForKey(); | |
1059 } | |
1060 | |
1056 void WebMediaPlayerImpl::OnHidden() { | 1061 void WebMediaPlayerImpl::OnHidden() { |
1057 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1062 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1058 UpdatePlayState(); | 1063 UpdatePlayState(); |
1059 } | 1064 } |
1060 | 1065 |
1061 void WebMediaPlayerImpl::OnShown() { | 1066 void WebMediaPlayerImpl::OnShown() { |
1062 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1067 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1063 must_suspend_ = false; | 1068 must_suspend_ = false; |
1064 UpdatePlayState(); | 1069 UpdatePlayState(); |
1065 } | 1070 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1241 DCHECK(data_source_); | 1246 DCHECK(data_source_); |
1242 | 1247 |
1243 #if !defined(MEDIA_DISABLE_FFMPEG) | 1248 #if !defined(MEDIA_DISABLE_FFMPEG) |
1244 Demuxer::MediaTracksUpdatedCB media_tracks_updated_cb = | 1249 Demuxer::MediaTracksUpdatedCB media_tracks_updated_cb = |
1245 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated); | 1250 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnFFmpegMediaTracksUpdated); |
1246 | 1251 |
1247 demuxer_.reset(new FFmpegDemuxer(media_task_runner_, data_source_.get(), | 1252 demuxer_.reset(new FFmpegDemuxer(media_task_runner_, data_source_.get(), |
1248 encrypted_media_init_data_cb, | 1253 encrypted_media_init_data_cb, |
1249 media_tracks_updated_cb, media_log_)); | 1254 media_tracks_updated_cb, media_log_)); |
1250 #else | 1255 #else |
1251 OnPipelineError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN); | 1256 OnError(PipelineStatus::DEMUXER_ERROR_COULD_NOT_OPEN); |
1252 return; | 1257 return; |
1253 #endif | 1258 #endif |
1254 } else { | 1259 } else { |
1255 DCHECK(!chunk_demuxer_); | 1260 DCHECK(!chunk_demuxer_); |
1256 DCHECK(!data_source_); | 1261 DCHECK(!data_source_); |
1257 | 1262 |
1258 chunk_demuxer_ = new ChunkDemuxer( | 1263 chunk_demuxer_ = new ChunkDemuxer( |
1259 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), | 1264 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), |
1260 encrypted_media_init_data_cb, media_log_, true); | 1265 encrypted_media_init_data_cb, media_log_, true); |
1261 demuxer_.reset(chunk_demuxer_); | 1266 demuxer_.reset(chunk_demuxer_); |
1262 } | 1267 } |
1263 | 1268 |
1264 // TODO(sandersd): FileSystem objects may also be non-static, but due to our | 1269 // TODO(sandersd): FileSystem objects may also be non-static, but due to our |
1265 // caching layer such situations are broken already. http://crbug.com/593159 | 1270 // caching layer such situations are broken already. http://crbug.com/593159 |
1266 bool is_static = !chunk_demuxer_; | 1271 bool is_static = !chunk_demuxer_; |
1267 | 1272 |
1268 // ... and we're ready to go! | 1273 // ... and we're ready to go! |
1269 seeking_ = true; | 1274 seeking_ = true; |
1270 | 1275 |
1271 // TODO(sandersd): On Android, defer Start() if the tab is not visible. | 1276 // TODO(sandersd): On Android, defer Start() if the tab is not visible. |
1272 bool is_streaming = (data_source_ && data_source_->IsStreaming()); | 1277 bool is_streaming = (data_source_ && data_source_->IsStreaming()); |
1273 pipeline_controller_.Start( | 1278 pipeline_controller_.Start(demuxer_.get(), this, is_streaming, is_static); |
1274 demuxer_.get(), is_streaming, is_static, | |
1275 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | |
1276 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), | |
1277 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), | |
1278 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged), | |
1279 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack), | |
1280 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnWaitingForDecryptionKey)); | |
1281 } | 1279 } |
1282 | 1280 |
1283 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 1281 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
1284 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 1282 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
1285 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1283 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1286 network_state_ = state; | 1284 network_state_ = state; |
1287 // Always notify to ensure client has the latest value. | 1285 // Always notify to ensure client has the latest value. |
1288 client_->networkStateChanged(); | 1286 client_->networkStateChanged(); |
1289 } | 1287 } |
1290 | 1288 |
(...skipping 21 matching lines...) Expand all Loading... | |
1312 base::TimeDelta duration = pipeline_.GetMediaDuration(); | 1310 base::TimeDelta duration = pipeline_.GetMediaDuration(); |
1313 | 1311 |
1314 // Return positive infinity if the resource is unbounded. | 1312 // Return positive infinity if the resource is unbounded. |
1315 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom- media-duration | 1313 // http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#dom- media-duration |
1316 if (duration == kInfiniteDuration()) | 1314 if (duration == kInfiniteDuration()) |
1317 return std::numeric_limits<double>::infinity(); | 1315 return std::numeric_limits<double>::infinity(); |
1318 | 1316 |
1319 return duration.InSecondsF(); | 1317 return duration.InSecondsF(); |
1320 } | 1318 } |
1321 | 1319 |
1322 void WebMediaPlayerImpl::OnDurationChanged() { | |
1323 // TODO(sandersd): We should call delegate_->DidPlay() with the new duration, | |
1324 // especially if it changed from <5s to >5s. | |
1325 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | |
1326 return; | |
1327 | |
1328 client_->durationChanged(); | |
1329 } | |
1330 | |
1331 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { | 1320 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
1332 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1321 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1333 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1322 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
1334 | 1323 |
1335 if (size == pipeline_metadata_.natural_size) | 1324 if (size == pipeline_metadata_.natural_size) |
1336 return; | 1325 return; |
1337 | 1326 |
1338 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 1327 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
1339 media_log_->AddEvent( | 1328 media_log_->AddEvent( |
1340 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 1329 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1594 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1583 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
1595 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1584 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
1596 << ", Demuxer: " << demuxer_memory_usage; | 1585 << ", Demuxer: " << demuxer_memory_usage; |
1597 | 1586 |
1598 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1587 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
1599 last_reported_memory_usage_ = current_memory_usage; | 1588 last_reported_memory_usage_ = current_memory_usage; |
1600 adjust_allocated_memory_cb_.Run(delta); | 1589 adjust_allocated_memory_cb_.Run(delta); |
1601 } | 1590 } |
1602 | 1591 |
1603 } // namespace media | 1592 } // namespace media |
OLD | NEW |