OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/media/webmediaplayer_impl.h" | 5 #include "webkit/media/webmediaplayer_impl.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/message_loop_proxy.h" | 14 #include "base/message_loop_proxy.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
17 #include "base/synchronization/waitable_event.h" | 17 #include "base/synchronization/waitable_event.h" |
18 #include "media/audio/null_audio_sink.h" | 18 #include "media/audio/null_audio_sink.h" |
| 19 #include "media/base/bind_to_loop.h" |
19 #include "media/base/filter_collection.h" | 20 #include "media/base/filter_collection.h" |
20 #include "media/base/limits.h" | 21 #include "media/base/limits.h" |
21 #include "media/base/media_log.h" | 22 #include "media/base/media_log.h" |
22 #include "media/base/media_switches.h" | 23 #include "media/base/media_switches.h" |
23 #include "media/base/pipeline.h" | 24 #include "media/base/pipeline.h" |
24 #include "media/base/video_frame.h" | 25 #include "media/base/video_frame.h" |
25 #include "media/filters/audio_renderer_impl.h" | 26 #include "media/filters/audio_renderer_impl.h" |
26 #include "media/filters/video_renderer_base.h" | 27 #include "media/filters/video_renderer_base.h" |
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" |
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 | 84 |
84 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ | 85 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ |
85 COMPILE_ASSERT(static_cast<int>(WebKit::WebMediaPlayer::CORSMode ## name) == \ | 86 COMPILE_ASSERT(static_cast<int>(WebKit::WebMediaPlayer::CORSMode ## name) == \ |
86 static_cast<int>(BufferedResourceLoader::k ## name), \ | 87 static_cast<int>(BufferedResourceLoader::k ## name), \ |
87 mismatching_enums) | 88 mismatching_enums) |
88 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); | 89 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); |
89 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); | 90 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); |
90 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); | 91 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); |
91 #undef COMPILE_ASSERT_MATCHING_ENUM | 92 #undef COMPILE_ASSERT_MATCHING_ENUM |
92 | 93 |
| 94 #define BIND_TO_RENDER_LOOP(function) \ |
| 95 media::BindToLoop(main_loop_->message_loop_proxy(), base::Bind( \ |
| 96 function, weak_this_.GetWeakPtr())) |
| 97 |
93 static WebKit::WebTimeRanges ConvertToWebTimeRanges( | 98 static WebKit::WebTimeRanges ConvertToWebTimeRanges( |
94 const media::Ranges<base::TimeDelta>& ranges) { | 99 const media::Ranges<base::TimeDelta>& ranges) { |
95 WebKit::WebTimeRanges result(ranges.size()); | 100 WebKit::WebTimeRanges result(ranges.size()); |
96 for (size_t i = 0; i < ranges.size(); i++) { | 101 for (size_t i = 0; i < ranges.size(); i++) { |
97 result[i].start = ranges.start(i).InSecondsF(); | 102 result[i].start = ranges.start(i).InSecondsF(); |
98 result[i].end = ranges.end(i).InSecondsF(); | 103 result[i].end = ranges.end(i).InSecondsF(); |
99 } | 104 } |
100 return result; | 105 return result; |
101 } | 106 } |
102 | 107 |
(...skipping 22 matching lines...) Expand all Loading... |
125 proxy_(new WebMediaPlayerProxy(main_loop_->message_loop_proxy(), this)), | 130 proxy_(new WebMediaPlayerProxy(main_loop_->message_loop_proxy(), this)), |
126 delegate_(delegate), | 131 delegate_(delegate), |
127 media_stream_client_(media_stream_client), | 132 media_stream_client_(media_stream_client), |
128 media_log_(media_log), | 133 media_log_(media_log), |
129 accelerated_compositing_reported_(false), | 134 accelerated_compositing_reported_(false), |
130 incremented_externally_allocated_memory_(false), | 135 incremented_externally_allocated_memory_(false), |
131 audio_source_provider_(audio_source_provider), | 136 audio_source_provider_(audio_source_provider), |
132 audio_renderer_sink_(audio_renderer_sink), | 137 audio_renderer_sink_(audio_renderer_sink), |
133 is_local_source_(false), | 138 is_local_source_(false), |
134 supports_save_(true), | 139 supports_save_(true), |
135 decryptor_(proxy_.get(), client, frame) { | 140 decryptor_(proxy_.get(), client, frame), |
| 141 weak_this_(this) { |
136 media_log_->AddEvent( | 142 media_log_->AddEvent( |
137 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 143 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
138 | 144 |
139 scoped_refptr<base::MessageLoopProxy> pipeline_message_loop = | 145 scoped_refptr<base::MessageLoopProxy> pipeline_message_loop = |
140 message_loop_factory_->GetMessageLoop( | 146 message_loop_factory_->GetMessageLoop( |
141 media::MessageLoopFactory::kPipeline); | 147 media::MessageLoopFactory::kPipeline); |
142 pipeline_ = new media::Pipeline(pipeline_message_loop, media_log_); | 148 pipeline_ = new media::Pipeline(pipeline_message_loop, media_log_); |
143 | 149 |
144 // Let V8 know we started new thread if we did not did it yet. | 150 // Let V8 know we started new thread if we did not did it yet. |
145 // Made separate task to avoid deletion of player currently being created. | 151 // Made separate task to avoid deletion of player currently being created. |
146 // Also, delaying GC until after player starts gets rid of starting lag -- | 152 // Also, delaying GC until after player starts gets rid of starting lag -- |
147 // collection happens in parallel with playing. | 153 // collection happens in parallel with playing. |
148 // | 154 // |
149 // TODO(enal): remove when we get rid of per-audio-stream thread. | 155 // TODO(enal): remove when we get rid of per-audio-stream thread. |
150 MessageLoop::current()->PostTask( | 156 MessageLoop::current()->PostTask( |
151 FROM_HERE, | 157 FROM_HERE, |
152 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | 158 base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, |
153 AsWeakPtr())); | 159 AsWeakPtr())); |
154 | 160 |
155 // Also we want to be notified of |main_loop_| destruction. | 161 // Also we want to be notified of |main_loop_| destruction. |
156 main_loop_->AddDestructionObserver(this); | 162 main_loop_->AddDestructionObserver(this); |
157 | 163 |
158 // Create default video renderer. | 164 // Create default video renderer. |
159 scoped_refptr<media::VideoRendererBase> video_renderer = | 165 scoped_refptr<media::VideoRendererBase> video_renderer = |
160 new media::VideoRendererBase( | 166 new media::VideoRendererBase( |
161 base::Bind(&WebMediaPlayerProxy::Repaint, proxy_), | 167 base::Bind(&WebMediaPlayerProxy::Repaint, proxy_), |
162 base::Bind(&WebMediaPlayerProxy::SetOpaque, proxy_.get()), | 168 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::SetOpaque), |
163 true); | 169 true); |
164 filter_collection_->AddVideoRenderer(video_renderer); | 170 filter_collection_->AddVideoRenderer(video_renderer); |
165 proxy_->set_frame_provider(video_renderer); | 171 proxy_->set_frame_provider(video_renderer); |
166 | 172 |
167 // Create default audio renderer. | 173 // Create default audio renderer. |
168 filter_collection_->AddAudioRenderer( | 174 filter_collection_->AddAudioRenderer( |
169 new media::AudioRendererImpl(new media::NullAudioSink())); | 175 new media::AudioRendererImpl(new media::NullAudioSink())); |
170 } | 176 } |
171 | 177 |
172 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 178 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 &decryptor_)) { | 255 &decryptor_)) { |
250 supports_save_ = false; | 256 supports_save_ = false; |
251 StartPipeline(); | 257 StartPipeline(); |
252 return; | 258 return; |
253 } | 259 } |
254 | 260 |
255 // Otherwise it's a regular request which requires resolving the URL first. | 261 // Otherwise it's a regular request which requires resolving the URL first. |
256 proxy_->set_data_source( | 262 proxy_->set_data_source( |
257 new BufferedDataSource(main_loop_, frame_, media_log_, | 263 new BufferedDataSource(main_loop_, frame_, media_log_, |
258 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, | 264 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, |
259 base::Unretained(this)))); | 265 weak_this_.GetWeakPtr()))); |
260 proxy_->data_source()->Initialize( | 266 proxy_->data_source()->Initialize( |
261 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 267 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
262 base::Bind( | 268 base::Bind( |
263 &WebMediaPlayerImpl::DataSourceInitialized, | 269 &WebMediaPlayerImpl::DataSourceInitialized, |
264 base::Unretained(this), gurl)); | 270 weak_this_.GetWeakPtr(), gurl)); |
265 | 271 |
266 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 272 is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |
267 | 273 |
268 BuildDefaultCollection(proxy_->data_source(), | 274 BuildDefaultCollection(proxy_->data_source(), |
269 message_loop_factory_.get(), | 275 message_loop_factory_.get(), |
270 filter_collection_.get(), | 276 filter_collection_.get(), |
271 &decryptor_); | 277 &decryptor_); |
272 } | 278 } |
273 | 279 |
274 void WebMediaPlayerImpl::cancelLoad() { | 280 void WebMediaPlayerImpl::cancelLoad() { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 if (paused_) | 334 if (paused_) |
329 paused_time_ = seek_time; | 335 paused_time_ = seek_time; |
330 | 336 |
331 seeking_ = true; | 337 seeking_ = true; |
332 | 338 |
333 proxy_->DemuxerStartWaitingForSeek(); | 339 proxy_->DemuxerStartWaitingForSeek(); |
334 | 340 |
335 // Kick off the asynchronous seek! | 341 // Kick off the asynchronous seek! |
336 pipeline_->Seek( | 342 pipeline_->Seek( |
337 seek_time, | 343 seek_time, |
338 base::Bind(&WebMediaPlayerProxy::PipelineSeekCallback, | 344 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineSeek)); |
339 proxy_.get())); | |
340 } | 345 } |
341 | 346 |
342 void WebMediaPlayerImpl::setEndTime(float seconds) { | 347 void WebMediaPlayerImpl::setEndTime(float seconds) { |
343 DCHECK_EQ(main_loop_, MessageLoop::current()); | 348 DCHECK_EQ(main_loop_, MessageLoop::current()); |
344 | 349 |
345 // TODO(hclam): add method call when it has been implemented. | 350 // TODO(hclam): add method call when it has been implemented. |
346 return; | 351 return; |
347 } | 352 } |
348 | 353 |
349 void WebMediaPlayerImpl::setRate(float rate) { | 354 void WebMediaPlayerImpl::setRate(float rate) { |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 965 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
961 media_log_->AddEvent( | 966 media_log_->AddEvent( |
962 media_log_->CreateBooleanEvent( | 967 media_log_->CreateBooleanEvent( |
963 media::MediaLogEvent::NETWORK_ACTIVITY_SET, | 968 media::MediaLogEvent::NETWORK_ACTIVITY_SET, |
964 "is_downloading_data", is_downloading)); | 969 "is_downloading_data", is_downloading)); |
965 } | 970 } |
966 | 971 |
967 void WebMediaPlayerImpl::StartPipeline() { | 972 void WebMediaPlayerImpl::StartPipeline() { |
968 pipeline_->Start( | 973 pipeline_->Start( |
969 filter_collection_.Pass(), | 974 filter_collection_.Pass(), |
970 base::Bind(&WebMediaPlayerProxy::PipelineEndedCallback, proxy_.get()), | 975 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
971 base::Bind(&WebMediaPlayerProxy::PipelineErrorCallback, proxy_.get()), | 976 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
972 base::Bind(&WebMediaPlayerProxy::PipelineInitializationCallback, | 977 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineInitialize)); |
973 proxy_.get())); | |
974 } | 978 } |
975 | 979 |
976 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 980 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
977 DCHECK_EQ(main_loop_, MessageLoop::current()); | 981 DCHECK_EQ(main_loop_, MessageLoop::current()); |
978 DVLOG(1) << "SetNetworkState: " << state; | 982 DVLOG(1) << "SetNetworkState: " << state; |
979 network_state_ = state; | 983 network_state_ = state; |
980 // Always notify to ensure client has the latest value. | 984 // Always notify to ensure client has the latest value. |
981 GetClient()->networkStateChanged(); | 985 GetClient()->networkStateChanged(); |
982 } | 986 } |
983 | 987 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 return audio_source_provider_; | 1036 return audio_source_provider_; |
1033 } | 1037 } |
1034 | 1038 |
1035 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 1039 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |
1036 DCHECK_EQ(main_loop_, MessageLoop::current()); | 1040 DCHECK_EQ(main_loop_, MessageLoop::current()); |
1037 incremented_externally_allocated_memory_ = true; | 1041 incremented_externally_allocated_memory_ = true; |
1038 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 1042 v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |
1039 } | 1043 } |
1040 | 1044 |
1041 } // namespace webkit_media | 1045 } // namespace webkit_media |
OLD | NEW |