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 "content/renderer/media/webmediaplayer_impl.h" | 5 #include "content/renderer/media/webmediaplayer_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
16 #include "base/debug/alias.h" | 16 #include "base/debug/alias.h" |
17 #include "base/debug/crash_logging.h" | 17 #include "base/debug/crash_logging.h" |
18 #include "base/debug/trace_event.h" | 18 #include "base/debug/trace_event.h" |
19 #include "base/message_loop/message_loop_proxy.h" | 19 #include "base/message_loop/message_loop_proxy.h" |
20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 21 #include "base/single_thread_task_runner.h" |
21 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
22 #include "cc/blink/web_layer_impl.h" | 23 #include "cc/blink/web_layer_impl.h" |
23 #include "cc/layers/video_layer.h" | 24 #include "cc/layers/video_layer.h" |
24 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
25 #include "content/public/renderer/render_frame.h" | 26 #include "content/public/renderer/render_frame.h" |
26 #include "content/renderer/media/buffered_data_source.h" | 27 #include "content/renderer/media/buffered_data_source.h" |
27 #include "content/renderer/media/crypto/encrypted_media_player_support.h" | 28 #include "content/renderer/media/crypto/encrypted_media_player_support.h" |
28 #include "content/renderer/media/render_media_log.h" | 29 #include "content/renderer/media/render_media_log.h" |
29 #include "content/renderer/media/texttrack_impl.h" | 30 #include "content/renderer/media/texttrack_impl.h" |
30 #include "content/renderer/media/webaudiosourceprovider_impl.h" | 31 #include "content/renderer/media/webaudiosourceprovider_impl.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ | 121 #define COMPILE_ASSERT_MATCHING_ENUM(name) \ |
121 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ | 122 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ |
122 static_cast<int>(BufferedResourceLoader::k ## name), \ | 123 static_cast<int>(BufferedResourceLoader::k ## name), \ |
123 mismatching_enums) | 124 mismatching_enums) |
124 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); | 125 COMPILE_ASSERT_MATCHING_ENUM(Unspecified); |
125 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); | 126 COMPILE_ASSERT_MATCHING_ENUM(Anonymous); |
126 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); | 127 COMPILE_ASSERT_MATCHING_ENUM(UseCredentials); |
127 #undef COMPILE_ASSERT_MATCHING_ENUM | 128 #undef COMPILE_ASSERT_MATCHING_ENUM |
128 | 129 |
129 #define BIND_TO_RENDER_LOOP(function) \ | 130 #define BIND_TO_RENDER_LOOP(function) \ |
130 (DCHECK(main_loop_->BelongsToCurrentThread()), \ | 131 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
131 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) | 132 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) |
132 | 133 |
133 #define BIND_TO_RENDER_LOOP1(function, arg1) \ | 134 #define BIND_TO_RENDER_LOOP1(function, arg1) \ |
134 (DCHECK(main_loop_->BelongsToCurrentThread()), \ | 135 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
135 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) | 136 media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) |
136 | 137 |
137 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, | 138 static void LogMediaSourceError(const scoped_refptr<media::MediaLog>& media_log, |
138 const std::string& error) { | 139 const std::string& error) { |
139 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); | 140 media_log->AddEvent(media_log->CreateMediaSourceErrorEvent(error)); |
140 } | 141 } |
141 | 142 |
142 WebMediaPlayerImpl::WebMediaPlayerImpl( | 143 WebMediaPlayerImpl::WebMediaPlayerImpl( |
143 blink::WebLocalFrame* frame, | 144 blink::WebLocalFrame* frame, |
144 blink::WebMediaPlayerClient* client, | 145 blink::WebMediaPlayerClient* client, |
145 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 146 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
146 const WebMediaPlayerParams& params) | 147 const WebMediaPlayerParams& params) |
147 : frame_(frame), | 148 : frame_(frame), |
148 network_state_(WebMediaPlayer::NetworkStateEmpty), | 149 network_state_(WebMediaPlayer::NetworkStateEmpty), |
149 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 150 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
150 preload_(AUTO), | 151 preload_(AUTO), |
151 main_loop_(base::MessageLoopProxy::current()), | 152 main_task_runner_(base::MessageLoopProxy::current()), |
152 media_loop_( | 153 media_task_runner_( |
153 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), | 154 RenderThreadImpl::current()->GetMediaThreadTaskRunner()), |
154 media_log_(new RenderMediaLog()), | 155 media_log_(new RenderMediaLog()), |
155 pipeline_(media_loop_, media_log_.get()), | 156 pipeline_(media_task_runner_, media_log_.get()), |
156 load_type_(LoadTypeURL), | 157 load_type_(LoadTypeURL), |
157 opaque_(false), | 158 opaque_(false), |
158 paused_(true), | 159 paused_(true), |
159 seeking_(false), | 160 seeking_(false), |
160 playback_rate_(0.0f), | 161 playback_rate_(0.0f), |
161 pending_seek_(false), | 162 pending_seek_(false), |
162 pending_seek_seconds_(0.0f), | 163 pending_seek_seconds_(0.0f), |
163 should_notify_time_changed_(false), | 164 should_notify_time_changed_(false), |
164 client_(client), | 165 client_(client), |
165 delegate_(delegate), | 166 delegate_(delegate), |
(...skipping 13 matching lines...) Expand all Loading... |
179 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { | 180 encrypted_media_support_(EncryptedMediaPlayerSupport::Create(client)) { |
180 DCHECK(encrypted_media_support_); | 181 DCHECK(encrypted_media_support_); |
181 | 182 |
182 media_log_->AddEvent( | 183 media_log_->AddEvent( |
183 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 184 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
184 | 185 |
185 // |gpu_factories_| requires that its entry points be called on its | 186 // |gpu_factories_| requires that its entry points be called on its |
186 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the | 187 // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the |
187 // factories, require that their message loops are identical. | 188 // factories, require that their message loops are identical. |
188 DCHECK(!gpu_factories_.get() || | 189 DCHECK(!gpu_factories_.get() || |
189 (gpu_factories_->GetTaskRunner() == media_loop_.get())); | 190 (gpu_factories_->GetTaskRunner() == media_task_runner_.get())); |
190 | 191 |
191 // Use the null sink if no sink was provided. | 192 // Use the null sink if no sink was provided. |
192 audio_source_provider_ = new WebAudioSourceProviderImpl( | 193 audio_source_provider_ = new WebAudioSourceProviderImpl( |
193 params.audio_renderer_sink().get() | 194 params.audio_renderer_sink().get() |
194 ? params.audio_renderer_sink() | 195 ? params.audio_renderer_sink() |
195 : new media::NullAudioSink(media_loop_)); | 196 : new media::NullAudioSink(media_task_runner_)); |
196 } | 197 } |
197 | 198 |
198 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 199 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |
199 client_->setWebLayer(NULL); | 200 client_->setWebLayer(NULL); |
200 | 201 |
201 DCHECK(main_loop_->BelongsToCurrentThread()); | 202 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
202 media_log_->AddEvent( | 203 media_log_->AddEvent( |
203 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 204 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |
204 | 205 |
205 if (delegate_.get()) | 206 if (delegate_.get()) |
206 delegate_->PlayerGone(this); | 207 delegate_->PlayerGone(this); |
207 | 208 |
208 // Abort any pending IO so stopping the pipeline doesn't get blocked. | 209 // Abort any pending IO so stopping the pipeline doesn't get blocked. |
209 if (data_source_) | 210 if (data_source_) |
210 data_source_->Abort(); | 211 data_source_->Abort(); |
211 if (chunk_demuxer_) { | 212 if (chunk_demuxer_) { |
(...skipping 21 matching lines...) Expand all Loading... |
233 defer_load_cb_.Run(base::Bind( | 234 defer_load_cb_.Run(base::Bind( |
234 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); | 235 &WebMediaPlayerImpl::DoLoad, AsWeakPtr(), load_type, url, cors_mode)); |
235 return; | 236 return; |
236 } | 237 } |
237 DoLoad(load_type, url, cors_mode); | 238 DoLoad(load_type, url, cors_mode); |
238 } | 239 } |
239 | 240 |
240 void WebMediaPlayerImpl::DoLoad(LoadType load_type, | 241 void WebMediaPlayerImpl::DoLoad(LoadType load_type, |
241 const blink::WebURL& url, | 242 const blink::WebURL& url, |
242 CORSMode cors_mode) { | 243 CORSMode cors_mode) { |
243 DCHECK(main_loop_->BelongsToCurrentThread()); | 244 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
244 | 245 |
245 GURL gurl(url); | 246 GURL gurl(url); |
246 ReportMediaSchemeUma(gurl); | 247 ReportMediaSchemeUma(gurl); |
247 | 248 |
248 // Set subresource URL for crash reporting. | 249 // Set subresource URL for crash reporting. |
249 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); | 250 base::debug::SetCrashKeyValue("subresource_url", gurl.spec()); |
250 | 251 |
251 load_type_ = load_type; | 252 load_type_ = load_type; |
252 | 253 |
253 SetNetworkState(WebMediaPlayer::NetworkStateLoading); | 254 SetNetworkState(WebMediaPlayer::NetworkStateLoading); |
254 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); | 255 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); |
255 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); | 256 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); |
256 | 257 |
257 // Media source pipelines can start immediately. | 258 // Media source pipelines can start immediately. |
258 if (load_type == LoadTypeMediaSource) { | 259 if (load_type == LoadTypeMediaSource) { |
259 supports_save_ = false; | 260 supports_save_ = false; |
260 StartPipeline(); | 261 StartPipeline(); |
261 return; | 262 return; |
262 } | 263 } |
263 | 264 |
264 // Otherwise it's a regular request which requires resolving the URL first. | 265 // Otherwise it's a regular request which requires resolving the URL first. |
265 data_source_.reset(new BufferedDataSource( | 266 data_source_.reset(new BufferedDataSource( |
266 url, | 267 url, |
267 static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 268 static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
268 main_loop_, | 269 main_task_runner_, |
269 frame_, | 270 frame_, |
270 media_log_.get(), | 271 media_log_.get(), |
271 &buffered_data_source_host_, | 272 &buffered_data_source_host_, |
272 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 273 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
273 data_source_->Initialize( | 274 data_source_->Initialize( |
274 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); | 275 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); |
275 data_source_->SetPreload(preload_); | 276 data_source_->SetPreload(preload_); |
276 } | 277 } |
277 | 278 |
278 void WebMediaPlayerImpl::play() { | 279 void WebMediaPlayerImpl::play() { |
279 DVLOG(1) << __FUNCTION__; | 280 DVLOG(1) << __FUNCTION__; |
280 DCHECK(main_loop_->BelongsToCurrentThread()); | 281 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
281 | 282 |
282 paused_ = false; | 283 paused_ = false; |
283 pipeline_.SetPlaybackRate(playback_rate_); | 284 pipeline_.SetPlaybackRate(playback_rate_); |
284 if (data_source_) | 285 if (data_source_) |
285 data_source_->MediaIsPlaying(); | 286 data_source_->MediaIsPlaying(); |
286 | 287 |
287 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); | 288 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PLAY)); |
288 | 289 |
289 if (delegate_.get()) | 290 if (delegate_.get()) |
290 delegate_->DidPlay(this); | 291 delegate_->DidPlay(this); |
291 } | 292 } |
292 | 293 |
293 void WebMediaPlayerImpl::pause() { | 294 void WebMediaPlayerImpl::pause() { |
294 DVLOG(1) << __FUNCTION__; | 295 DVLOG(1) << __FUNCTION__; |
295 DCHECK(main_loop_->BelongsToCurrentThread()); | 296 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
296 | 297 |
297 paused_ = true; | 298 paused_ = true; |
298 pipeline_.SetPlaybackRate(0.0f); | 299 pipeline_.SetPlaybackRate(0.0f); |
299 if (data_source_) | 300 if (data_source_) |
300 data_source_->MediaIsPaused(); | 301 data_source_->MediaIsPaused(); |
301 paused_time_ = pipeline_.GetMediaTime(); | 302 paused_time_ = pipeline_.GetMediaTime(); |
302 | 303 |
303 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE)); | 304 media_log_->AddEvent(media_log_->CreateEvent(media::MediaLogEvent::PAUSE)); |
304 | 305 |
305 if (delegate_.get()) | 306 if (delegate_.get()) |
306 delegate_->DidPause(this); | 307 delegate_->DidPause(this); |
307 } | 308 } |
308 | 309 |
309 bool WebMediaPlayerImpl::supportsSave() const { | 310 bool WebMediaPlayerImpl::supportsSave() const { |
310 DCHECK(main_loop_->BelongsToCurrentThread()); | 311 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
311 return supports_save_; | 312 return supports_save_; |
312 } | 313 } |
313 | 314 |
314 void WebMediaPlayerImpl::seek(double seconds) { | 315 void WebMediaPlayerImpl::seek(double seconds) { |
315 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; | 316 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; |
316 DCHECK(main_loop_->BelongsToCurrentThread()); | 317 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
317 | 318 |
318 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) | 319 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) |
319 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 320 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
320 | 321 |
321 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); | 322 base::TimeDelta seek_time = ConvertSecondsToTimestamp(seconds); |
322 | 323 |
323 if (seeking_) { | 324 if (seeking_) { |
324 pending_seek_ = true; | 325 pending_seek_ = true; |
325 pending_seek_seconds_ = seconds; | 326 pending_seek_seconds_ = seconds; |
326 if (chunk_demuxer_) | 327 if (chunk_demuxer_) |
(...skipping 13 matching lines...) Expand all Loading... |
340 chunk_demuxer_->StartWaitingForSeek(seek_time); | 341 chunk_demuxer_->StartWaitingForSeek(seek_time); |
341 | 342 |
342 // Kick off the asynchronous seek! | 343 // Kick off the asynchronous seek! |
343 pipeline_.Seek( | 344 pipeline_.Seek( |
344 seek_time, | 345 seek_time, |
345 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, true)); | 346 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, true)); |
346 } | 347 } |
347 | 348 |
348 void WebMediaPlayerImpl::setRate(double rate) { | 349 void WebMediaPlayerImpl::setRate(double rate) { |
349 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; | 350 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; |
350 DCHECK(main_loop_->BelongsToCurrentThread()); | 351 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
351 | 352 |
352 // TODO(kylep): Remove when support for negatives is added. Also, modify the | 353 // TODO(kylep): Remove when support for negatives is added. Also, modify the |
353 // following checks so rewind uses reasonable values also. | 354 // following checks so rewind uses reasonable values also. |
354 if (rate < 0.0) | 355 if (rate < 0.0) |
355 return; | 356 return; |
356 | 357 |
357 // Limit rates to reasonable values by clamping. | 358 // Limit rates to reasonable values by clamping. |
358 if (rate != 0.0) { | 359 if (rate != 0.0) { |
359 if (rate < kMinRate) | 360 if (rate < kMinRate) |
360 rate = kMinRate; | 361 rate = kMinRate; |
361 else if (rate > kMaxRate) | 362 else if (rate > kMaxRate) |
362 rate = kMaxRate; | 363 rate = kMaxRate; |
363 } | 364 } |
364 | 365 |
365 playback_rate_ = rate; | 366 playback_rate_ = rate; |
366 if (!paused_) { | 367 if (!paused_) { |
367 pipeline_.SetPlaybackRate(rate); | 368 pipeline_.SetPlaybackRate(rate); |
368 if (data_source_) | 369 if (data_source_) |
369 data_source_->MediaPlaybackRateChanged(rate); | 370 data_source_->MediaPlaybackRateChanged(rate); |
370 } | 371 } |
371 } | 372 } |
372 | 373 |
373 void WebMediaPlayerImpl::setVolume(double volume) { | 374 void WebMediaPlayerImpl::setVolume(double volume) { |
374 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; | 375 DVLOG(1) << __FUNCTION__ << "(" << volume << ")"; |
375 DCHECK(main_loop_->BelongsToCurrentThread()); | 376 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
376 | 377 |
377 pipeline_.SetVolume(volume); | 378 pipeline_.SetVolume(volume); |
378 } | 379 } |
379 | 380 |
380 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ | 381 #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ |
381 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::webkit_name) == \ | 382 COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::webkit_name) == \ |
382 static_cast<int>(content::chromium_name), \ | 383 static_cast<int>(content::chromium_name), \ |
383 mismatching_enums) | 384 mismatching_enums) |
384 COMPILE_ASSERT_MATCHING_ENUM(PreloadNone, NONE); | 385 COMPILE_ASSERT_MATCHING_ENUM(PreloadNone, NONE); |
385 COMPILE_ASSERT_MATCHING_ENUM(PreloadMetaData, METADATA); | 386 COMPILE_ASSERT_MATCHING_ENUM(PreloadMetaData, METADATA); |
386 COMPILE_ASSERT_MATCHING_ENUM(PreloadAuto, AUTO); | 387 COMPILE_ASSERT_MATCHING_ENUM(PreloadAuto, AUTO); |
387 #undef COMPILE_ASSERT_MATCHING_ENUM | 388 #undef COMPILE_ASSERT_MATCHING_ENUM |
388 | 389 |
389 void WebMediaPlayerImpl::setPreload(WebMediaPlayer::Preload preload) { | 390 void WebMediaPlayerImpl::setPreload(WebMediaPlayer::Preload preload) { |
390 DVLOG(1) << __FUNCTION__ << "(" << preload << ")"; | 391 DVLOG(1) << __FUNCTION__ << "(" << preload << ")"; |
391 DCHECK(main_loop_->BelongsToCurrentThread()); | 392 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
392 | 393 |
393 preload_ = static_cast<content::Preload>(preload); | 394 preload_ = static_cast<content::Preload>(preload); |
394 if (data_source_) | 395 if (data_source_) |
395 data_source_->SetPreload(preload_); | 396 data_source_->SetPreload(preload_); |
396 } | 397 } |
397 | 398 |
398 bool WebMediaPlayerImpl::hasVideo() const { | 399 bool WebMediaPlayerImpl::hasVideo() const { |
399 DCHECK(main_loop_->BelongsToCurrentThread()); | 400 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
400 | 401 |
401 return pipeline_metadata_.has_video; | 402 return pipeline_metadata_.has_video; |
402 } | 403 } |
403 | 404 |
404 bool WebMediaPlayerImpl::hasAudio() const { | 405 bool WebMediaPlayerImpl::hasAudio() const { |
405 DCHECK(main_loop_->BelongsToCurrentThread()); | 406 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
406 | 407 |
407 return pipeline_metadata_.has_audio; | 408 return pipeline_metadata_.has_audio; |
408 } | 409 } |
409 | 410 |
410 blink::WebSize WebMediaPlayerImpl::naturalSize() const { | 411 blink::WebSize WebMediaPlayerImpl::naturalSize() const { |
411 DCHECK(main_loop_->BelongsToCurrentThread()); | 412 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
412 | 413 |
413 return blink::WebSize(pipeline_metadata_.natural_size); | 414 return blink::WebSize(pipeline_metadata_.natural_size); |
414 } | 415 } |
415 | 416 |
416 bool WebMediaPlayerImpl::paused() const { | 417 bool WebMediaPlayerImpl::paused() const { |
417 DCHECK(main_loop_->BelongsToCurrentThread()); | 418 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
418 | 419 |
419 return pipeline_.GetPlaybackRate() == 0.0f; | 420 return pipeline_.GetPlaybackRate() == 0.0f; |
420 } | 421 } |
421 | 422 |
422 bool WebMediaPlayerImpl::seeking() const { | 423 bool WebMediaPlayerImpl::seeking() const { |
423 DCHECK(main_loop_->BelongsToCurrentThread()); | 424 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
424 | 425 |
425 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 426 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
426 return false; | 427 return false; |
427 | 428 |
428 return seeking_; | 429 return seeking_; |
429 } | 430 } |
430 | 431 |
431 double WebMediaPlayerImpl::duration() const { | 432 double WebMediaPlayerImpl::duration() const { |
432 DCHECK(main_loop_->BelongsToCurrentThread()); | 433 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
433 | 434 |
434 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 435 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
435 return std::numeric_limits<double>::quiet_NaN(); | 436 return std::numeric_limits<double>::quiet_NaN(); |
436 | 437 |
437 return GetPipelineDuration(); | 438 return GetPipelineDuration(); |
438 } | 439 } |
439 | 440 |
440 double WebMediaPlayerImpl::timelineOffset() const { | 441 double WebMediaPlayerImpl::timelineOffset() const { |
441 DCHECK(main_loop_->BelongsToCurrentThread()); | 442 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
442 | 443 |
443 if (pipeline_metadata_.timeline_offset.is_null()) | 444 if (pipeline_metadata_.timeline_offset.is_null()) |
444 return std::numeric_limits<double>::quiet_NaN(); | 445 return std::numeric_limits<double>::quiet_NaN(); |
445 | 446 |
446 return pipeline_metadata_.timeline_offset.ToJsTime(); | 447 return pipeline_metadata_.timeline_offset.ToJsTime(); |
447 } | 448 } |
448 | 449 |
449 double WebMediaPlayerImpl::currentTime() const { | 450 double WebMediaPlayerImpl::currentTime() const { |
450 DCHECK(main_loop_->BelongsToCurrentThread()); | 451 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
451 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); | 452 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); |
452 } | 453 } |
453 | 454 |
454 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { | 455 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { |
455 DCHECK(main_loop_->BelongsToCurrentThread()); | 456 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
456 return network_state_; | 457 return network_state_; |
457 } | 458 } |
458 | 459 |
459 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { | 460 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { |
460 DCHECK(main_loop_->BelongsToCurrentThread()); | 461 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
461 return ready_state_; | 462 return ready_state_; |
462 } | 463 } |
463 | 464 |
464 blink::WebTimeRanges WebMediaPlayerImpl::buffered() const { | 465 blink::WebTimeRanges WebMediaPlayerImpl::buffered() const { |
465 DCHECK(main_loop_->BelongsToCurrentThread()); | 466 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
466 | 467 |
467 media::Ranges<base::TimeDelta> buffered_time_ranges = | 468 media::Ranges<base::TimeDelta> buffered_time_ranges = |
468 pipeline_.GetBufferedTimeRanges(); | 469 pipeline_.GetBufferedTimeRanges(); |
469 | 470 |
470 const base::TimeDelta duration = pipeline_.GetMediaDuration(); | 471 const base::TimeDelta duration = pipeline_.GetMediaDuration(); |
471 if (duration != media::kInfiniteDuration()) { | 472 if (duration != media::kInfiniteDuration()) { |
472 buffered_data_source_host_.AddBufferedTimeRanges( | 473 buffered_data_source_host_.AddBufferedTimeRanges( |
473 &buffered_time_ranges, duration); | 474 &buffered_time_ranges, duration); |
474 } | 475 } |
475 return ConvertToWebTimeRanges(buffered_time_ranges); | 476 return ConvertToWebTimeRanges(buffered_time_ranges); |
476 } | 477 } |
477 | 478 |
478 double WebMediaPlayerImpl::maxTimeSeekable() const { | 479 double WebMediaPlayerImpl::maxTimeSeekable() const { |
479 DCHECK(main_loop_->BelongsToCurrentThread()); | 480 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
480 | 481 |
481 // If we haven't even gotten to ReadyStateHaveMetadata yet then just | 482 // If we haven't even gotten to ReadyStateHaveMetadata yet then just |
482 // return 0 so that the seekable range is empty. | 483 // return 0 so that the seekable range is empty. |
483 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) | 484 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) |
484 return 0.0; | 485 return 0.0; |
485 | 486 |
486 // We don't support seeking in streaming media. | 487 // We don't support seeking in streaming media. |
487 if (data_source_ && data_source_->IsStreaming()) | 488 if (data_source_ && data_source_->IsStreaming()) |
488 return 0.0; | 489 return 0.0; |
489 return duration(); | 490 return duration(); |
490 } | 491 } |
491 | 492 |
492 bool WebMediaPlayerImpl::didLoadingProgress() { | 493 bool WebMediaPlayerImpl::didLoadingProgress() { |
493 DCHECK(main_loop_->BelongsToCurrentThread()); | 494 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
494 bool pipeline_progress = pipeline_.DidLoadingProgress(); | 495 bool pipeline_progress = pipeline_.DidLoadingProgress(); |
495 bool data_progress = buffered_data_source_host_.DidLoadingProgress(); | 496 bool data_progress = buffered_data_source_host_.DidLoadingProgress(); |
496 return pipeline_progress || data_progress; | 497 return pipeline_progress || data_progress; |
497 } | 498 } |
498 | 499 |
499 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, | 500 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, |
500 const blink::WebRect& rect, | 501 const blink::WebRect& rect, |
501 unsigned char alpha) { | 502 unsigned char alpha) { |
502 paint(canvas, rect, alpha, SkXfermode::kSrcOver_Mode); | 503 paint(canvas, rect, alpha, SkXfermode::kSrcOver_Mode); |
503 } | 504 } |
504 | 505 |
505 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, | 506 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, |
506 const blink::WebRect& rect, | 507 const blink::WebRect& rect, |
507 unsigned char alpha, | 508 unsigned char alpha, |
508 SkXfermode::Mode mode) { | 509 SkXfermode::Mode mode) { |
509 DCHECK(main_loop_->BelongsToCurrentThread()); | 510 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
510 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); | 511 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); |
511 | 512 |
512 // TODO(scherkus): Clarify paint() API contract to better understand when and | 513 // TODO(scherkus): Clarify paint() API contract to better understand when and |
513 // why it's being called. For example, today paint() is called when: | 514 // why it's being called. For example, today paint() is called when: |
514 // - We haven't reached HAVE_CURRENT_DATA and need to paint black | 515 // - We haven't reached HAVE_CURRENT_DATA and need to paint black |
515 // - We're painting to a canvas | 516 // - We're painting to a canvas |
516 // See http://crbug.com/341225 http://crbug.com/342621 for details. | 517 // See http://crbug.com/341225 http://crbug.com/342621 for details. |
517 scoped_refptr<media::VideoFrame> video_frame = | 518 scoped_refptr<media::VideoFrame> video_frame = |
518 GetCurrentFrameFromCompositor(); | 519 GetCurrentFrameFromCompositor(); |
519 | 520 |
(...skipping 17 matching lines...) Expand all Loading... |
537 if (data_source_) | 538 if (data_source_) |
538 return data_source_->DidPassCORSAccessCheck(); | 539 return data_source_->DidPassCORSAccessCheck(); |
539 return false; | 540 return false; |
540 } | 541 } |
541 | 542 |
542 double WebMediaPlayerImpl::mediaTimeForTimeValue(double timeValue) const { | 543 double WebMediaPlayerImpl::mediaTimeForTimeValue(double timeValue) const { |
543 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); | 544 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); |
544 } | 545 } |
545 | 546 |
546 unsigned WebMediaPlayerImpl::decodedFrameCount() const { | 547 unsigned WebMediaPlayerImpl::decodedFrameCount() const { |
547 DCHECK(main_loop_->BelongsToCurrentThread()); | 548 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
548 | 549 |
549 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 550 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
550 return stats.video_frames_decoded; | 551 return stats.video_frames_decoded; |
551 } | 552 } |
552 | 553 |
553 unsigned WebMediaPlayerImpl::droppedFrameCount() const { | 554 unsigned WebMediaPlayerImpl::droppedFrameCount() const { |
554 DCHECK(main_loop_->BelongsToCurrentThread()); | 555 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
555 | 556 |
556 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 557 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
557 return stats.video_frames_dropped; | 558 return stats.video_frames_dropped; |
558 } | 559 } |
559 | 560 |
560 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { | 561 unsigned WebMediaPlayerImpl::audioDecodedByteCount() const { |
561 DCHECK(main_loop_->BelongsToCurrentThread()); | 562 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
562 | 563 |
563 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 564 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
564 return stats.audio_bytes_decoded; | 565 return stats.audio_bytes_decoded; |
565 } | 566 } |
566 | 567 |
567 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { | 568 unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { |
568 DCHECK(main_loop_->BelongsToCurrentThread()); | 569 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
569 | 570 |
570 media::PipelineStatistics stats = pipeline_.GetStatistics(); | 571 media::PipelineStatistics stats = pipeline_.GetStatistics(); |
571 return stats.video_bytes_decoded; | 572 return stats.video_bytes_decoded; |
572 } | 573 } |
573 | 574 |
574 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( | 575 bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( |
575 blink::WebGraphicsContext3D* web_graphics_context, | 576 blink::WebGraphicsContext3D* web_graphics_context, |
576 unsigned int texture, | 577 unsigned int texture, |
577 unsigned int level, | 578 unsigned int level, |
578 unsigned int internal_format, | 579 unsigned int internal_format, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 | 622 |
622 SyncPointClientImpl client(web_graphics_context); | 623 SyncPointClientImpl client(web_graphics_context); |
623 video_frame->UpdateReleaseSyncPoint(&client); | 624 video_frame->UpdateReleaseSyncPoint(&client); |
624 return true; | 625 return true; |
625 } | 626 } |
626 | 627 |
627 WebMediaPlayer::MediaKeyException | 628 WebMediaPlayer::MediaKeyException |
628 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, | 629 WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, |
629 const unsigned char* init_data, | 630 const unsigned char* init_data, |
630 unsigned init_data_length) { | 631 unsigned init_data_length) { |
631 DCHECK(main_loop_->BelongsToCurrentThread()); | 632 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
632 | 633 |
633 return encrypted_media_support_->GenerateKeyRequest( | 634 return encrypted_media_support_->GenerateKeyRequest( |
634 frame_, key_system, init_data, init_data_length); | 635 frame_, key_system, init_data, init_data_length); |
635 } | 636 } |
636 | 637 |
637 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( | 638 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( |
638 const WebString& key_system, | 639 const WebString& key_system, |
639 const unsigned char* key, | 640 const unsigned char* key, |
640 unsigned key_length, | 641 unsigned key_length, |
641 const unsigned char* init_data, | 642 const unsigned char* init_data, |
642 unsigned init_data_length, | 643 unsigned init_data_length, |
643 const WebString& session_id) { | 644 const WebString& session_id) { |
644 DCHECK(main_loop_->BelongsToCurrentThread()); | 645 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
645 | 646 |
646 return encrypted_media_support_->AddKey( | 647 return encrypted_media_support_->AddKey( |
647 key_system, key, key_length, init_data, init_data_length, session_id); | 648 key_system, key, key_length, init_data, init_data_length, session_id); |
648 } | 649 } |
649 | 650 |
650 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( | 651 WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( |
651 const WebString& key_system, | 652 const WebString& key_system, |
652 const WebString& session_id) { | 653 const WebString& session_id) { |
653 DCHECK(main_loop_->BelongsToCurrentThread()); | 654 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
654 | 655 |
655 return encrypted_media_support_->CancelKeyRequest(key_system, session_id); | 656 return encrypted_media_support_->CancelKeyRequest(key_system, session_id); |
656 } | 657 } |
657 | 658 |
658 void WebMediaPlayerImpl::setContentDecryptionModule( | 659 void WebMediaPlayerImpl::setContentDecryptionModule( |
659 blink::WebContentDecryptionModule* cdm) { | 660 blink::WebContentDecryptionModule* cdm) { |
660 DCHECK(main_loop_->BelongsToCurrentThread()); | 661 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
661 | 662 |
662 encrypted_media_support_->SetContentDecryptionModule(cdm); | 663 encrypted_media_support_->SetContentDecryptionModule(cdm); |
663 } | 664 } |
664 | 665 |
665 void WebMediaPlayerImpl::setContentDecryptionModule( | 666 void WebMediaPlayerImpl::setContentDecryptionModule( |
666 blink::WebContentDecryptionModule* cdm, | 667 blink::WebContentDecryptionModule* cdm, |
667 blink::WebContentDecryptionModuleResult result) { | 668 blink::WebContentDecryptionModuleResult result) { |
668 DCHECK(main_loop_->BelongsToCurrentThread()); | 669 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
669 | 670 |
670 encrypted_media_support_->SetContentDecryptionModule(cdm, result); | 671 encrypted_media_support_->SetContentDecryptionModule(cdm, result); |
671 } | 672 } |
672 | 673 |
673 void WebMediaPlayerImpl::setContentDecryptionModuleSync( | 674 void WebMediaPlayerImpl::setContentDecryptionModuleSync( |
674 blink::WebContentDecryptionModule* cdm) { | 675 blink::WebContentDecryptionModule* cdm) { |
675 DCHECK(main_loop_->BelongsToCurrentThread()); | 676 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
676 | 677 |
677 encrypted_media_support_->SetContentDecryptionModuleSync(cdm); | 678 encrypted_media_support_->SetContentDecryptionModuleSync(cdm); |
678 } | 679 } |
679 | 680 |
680 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, | 681 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_changed, |
681 PipelineStatus status) { | 682 PipelineStatus status) { |
682 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; | 683 DVLOG(1) << __FUNCTION__ << "(" << time_changed << ", " << status << ")"; |
683 DCHECK(main_loop_->BelongsToCurrentThread()); | 684 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
684 seeking_ = false; | 685 seeking_ = false; |
685 if (pending_seek_) { | 686 if (pending_seek_) { |
686 pending_seek_ = false; | 687 pending_seek_ = false; |
687 seek(pending_seek_seconds_); | 688 seek(pending_seek_seconds_); |
688 return; | 689 return; |
689 } | 690 } |
690 | 691 |
691 if (status != media::PIPELINE_OK) { | 692 if (status != media::PIPELINE_OK) { |
692 OnPipelineError(status); | 693 OnPipelineError(status); |
693 return; | 694 return; |
694 } | 695 } |
695 | 696 |
696 // Update our paused time. | 697 // Update our paused time. |
697 if (paused_) | 698 if (paused_) |
698 paused_time_ = pipeline_.GetMediaTime(); | 699 paused_time_ = pipeline_.GetMediaTime(); |
699 | 700 |
700 should_notify_time_changed_ = time_changed; | 701 should_notify_time_changed_ = time_changed; |
701 } | 702 } |
702 | 703 |
703 void WebMediaPlayerImpl::OnPipelineEnded() { | 704 void WebMediaPlayerImpl::OnPipelineEnded() { |
704 DVLOG(1) << __FUNCTION__; | 705 DVLOG(1) << __FUNCTION__; |
705 DCHECK(main_loop_->BelongsToCurrentThread()); | 706 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
706 client_->timeChanged(); | 707 client_->timeChanged(); |
707 } | 708 } |
708 | 709 |
709 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { | 710 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { |
710 DCHECK(main_loop_->BelongsToCurrentThread()); | 711 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
711 DCHECK_NE(error, media::PIPELINE_OK); | 712 DCHECK_NE(error, media::PIPELINE_OK); |
712 | 713 |
713 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { | 714 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) { |
714 // Any error that occurs before reaching ReadyStateHaveMetadata should | 715 // Any error that occurs before reaching ReadyStateHaveMetadata should |
715 // be considered a format error. | 716 // be considered a format error. |
716 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 717 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
717 return; | 718 return; |
718 } | 719 } |
719 | 720 |
720 SetNetworkState(PipelineErrorToNetworkState(error)); | 721 SetNetworkState(PipelineErrorToNetworkState(error)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 // them and translate them ready state changes http://crbug.com/144683 | 764 // them and translate them ready state changes http://crbug.com/144683 |
764 DCHECK_EQ(buffering_state, media::BUFFERING_HAVE_ENOUGH); | 765 DCHECK_EQ(buffering_state, media::BUFFERING_HAVE_ENOUGH); |
765 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 766 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
766 | 767 |
767 // Blink expects a timeChanged() in response to a seek(). | 768 // Blink expects a timeChanged() in response to a seek(). |
768 if (should_notify_time_changed_) | 769 if (should_notify_time_changed_) |
769 client_->timeChanged(); | 770 client_->timeChanged(); |
770 } | 771 } |
771 | 772 |
772 void WebMediaPlayerImpl::OnDemuxerOpened() { | 773 void WebMediaPlayerImpl::OnDemuxerOpened() { |
773 DCHECK(main_loop_->BelongsToCurrentThread()); | 774 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
774 client_->mediaSourceOpened(new WebMediaSourceImpl( | 775 client_->mediaSourceOpened(new WebMediaSourceImpl( |
775 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); | 776 chunk_demuxer_, base::Bind(&LogMediaSourceError, media_log_))); |
776 } | 777 } |
777 | 778 |
778 void WebMediaPlayerImpl::OnAddTextTrack( | 779 void WebMediaPlayerImpl::OnAddTextTrack( |
779 const media::TextTrackConfig& config, | 780 const media::TextTrackConfig& config, |
780 const media::AddTextTrackDoneCB& done_cb) { | 781 const media::AddTextTrackDoneCB& done_cb) { |
781 DCHECK(main_loop_->BelongsToCurrentThread()); | 782 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
782 | 783 |
783 const WebInbandTextTrackImpl::Kind web_kind = | 784 const WebInbandTextTrackImpl::Kind web_kind = |
784 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); | 785 static_cast<WebInbandTextTrackImpl::Kind>(config.kind()); |
785 const blink::WebString web_label = | 786 const blink::WebString web_label = |
786 blink::WebString::fromUTF8(config.label()); | 787 blink::WebString::fromUTF8(config.label()); |
787 const blink::WebString web_language = | 788 const blink::WebString web_language = |
788 blink::WebString::fromUTF8(config.language()); | 789 blink::WebString::fromUTF8(config.language()); |
789 const blink::WebString web_id = | 790 const blink::WebString web_id = |
790 blink::WebString::fromUTF8(config.id()); | 791 blink::WebString::fromUTF8(config.id()); |
791 | 792 |
792 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track( | 793 scoped_ptr<WebInbandTextTrackImpl> web_inband_text_track( |
793 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id, | 794 new WebInbandTextTrackImpl(web_kind, web_label, web_language, web_id, |
794 text_track_index_++)); | 795 text_track_index_++)); |
795 | 796 |
796 scoped_ptr<media::TextTrack> text_track( | 797 scoped_ptr<media::TextTrack> text_track(new TextTrackImpl( |
797 new TextTrackImpl(main_loop_, client_, web_inband_text_track.Pass())); | 798 main_task_runner_, client_, web_inband_text_track.Pass())); |
798 | 799 |
799 done_cb.Run(text_track.Pass()); | 800 done_cb.Run(text_track.Pass()); |
800 } | 801 } |
801 | 802 |
802 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { | 803 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { |
803 DCHECK(main_loop_->BelongsToCurrentThread()); | 804 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
804 | 805 |
805 if (!success) { | 806 if (!success) { |
806 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 807 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
807 return; | 808 return; |
808 } | 809 } |
809 | 810 |
810 StartPipeline(); | 811 StartPipeline(); |
811 } | 812 } |
812 | 813 |
813 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { | 814 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { |
(...skipping 10 matching lines...) Expand all Loading... |
824 // TODO(xhwang): Move this to a factory class so that we can create different | 825 // TODO(xhwang): Move this to a factory class so that we can create different |
825 // renderers. | 826 // renderers. |
826 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() { | 827 scoped_ptr<media::Renderer> WebMediaPlayerImpl::CreateRenderer() { |
827 media::SetDecryptorReadyCB set_decryptor_ready_cb = | 828 media::SetDecryptorReadyCB set_decryptor_ready_cb = |
828 encrypted_media_support_->CreateSetDecryptorReadyCB(); | 829 encrypted_media_support_->CreateSetDecryptorReadyCB(); |
829 | 830 |
830 // Create our audio decoders and renderer. | 831 // Create our audio decoders and renderer. |
831 ScopedVector<media::AudioDecoder> audio_decoders; | 832 ScopedVector<media::AudioDecoder> audio_decoders; |
832 | 833 |
833 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_); | 834 media::LogCB log_cb = base::Bind(&LogMediaSourceError, media_log_); |
834 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_loop_, log_cb)); | 835 audio_decoders.push_back(new media::FFmpegAudioDecoder(media_task_runner_, |
835 audio_decoders.push_back(new media::OpusAudioDecoder(media_loop_)); | 836 log_cb)); |
| 837 audio_decoders.push_back(new media::OpusAudioDecoder(media_task_runner_)); |
836 | 838 |
837 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl( | 839 scoped_ptr<media::AudioRenderer> audio_renderer(new media::AudioRendererImpl( |
838 media_loop_, | 840 media_task_runner_, |
839 audio_source_provider_.get(), | 841 audio_source_provider_.get(), |
840 audio_decoders.Pass(), | 842 audio_decoders.Pass(), |
841 set_decryptor_ready_cb, | 843 set_decryptor_ready_cb, |
842 RenderThreadImpl::current()->GetAudioHardwareConfig())); | 844 RenderThreadImpl::current()->GetAudioHardwareConfig())); |
843 | 845 |
844 // Create our video decoders and renderer. | 846 // Create our video decoders and renderer. |
845 ScopedVector<media::VideoDecoder> video_decoders; | 847 ScopedVector<media::VideoDecoder> video_decoders; |
846 | 848 |
847 if (gpu_factories_.get()) { | 849 if (gpu_factories_.get()) { |
848 video_decoders.push_back( | 850 video_decoders.push_back( |
849 new media::GpuVideoDecoder(gpu_factories_, media_log_)); | 851 new media::GpuVideoDecoder(gpu_factories_, media_log_)); |
850 } | 852 } |
851 | 853 |
852 #if !defined(MEDIA_DISABLE_LIBVPX) | 854 #if !defined(MEDIA_DISABLE_LIBVPX) |
853 video_decoders.push_back(new media::VpxVideoDecoder(media_loop_)); | 855 video_decoders.push_back(new media::VpxVideoDecoder(media_task_runner_)); |
854 #endif // !defined(MEDIA_DISABLE_LIBVPX) | 856 #endif // !defined(MEDIA_DISABLE_LIBVPX) |
855 | 857 |
856 video_decoders.push_back(new media::FFmpegVideoDecoder(media_loop_)); | 858 video_decoders.push_back(new media::FFmpegVideoDecoder(media_task_runner_)); |
857 | 859 |
858 scoped_ptr<media::VideoRenderer> video_renderer( | 860 scoped_ptr<media::VideoRenderer> video_renderer( |
859 new media::VideoRendererImpl( | 861 new media::VideoRendererImpl( |
860 media_loop_, | 862 media_task_runner_, |
861 video_decoders.Pass(), | 863 video_decoders.Pass(), |
862 set_decryptor_ready_cb, | 864 set_decryptor_ready_cb, |
863 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), | 865 base::Bind(&WebMediaPlayerImpl::FrameReady, base::Unretained(this)), |
864 true)); | 866 true)); |
865 | 867 |
866 // Create renderer. | 868 // Create renderer. |
867 return scoped_ptr<media::Renderer>(new media::RendererImpl( | 869 return scoped_ptr<media::Renderer>(new media::RendererImpl( |
868 media_loop_, | 870 media_task_runner_, |
869 demuxer_.get(), | 871 demuxer_.get(), |
870 audio_renderer.Pass(), | 872 audio_renderer.Pass(), |
871 video_renderer.Pass())); | 873 video_renderer.Pass())); |
872 } | 874 } |
873 | 875 |
874 void WebMediaPlayerImpl::StartPipeline() { | 876 void WebMediaPlayerImpl::StartPipeline() { |
875 DCHECK(main_loop_->BelongsToCurrentThread()); | 877 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
876 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 878 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
877 | 879 |
878 // Keep track if this is a MSE or non-MSE playback. | 880 // Keep track if this is a MSE or non-MSE playback. |
879 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", | 881 UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", |
880 (load_type_ == LoadTypeMediaSource)); | 882 (load_type_ == LoadTypeMediaSource)); |
881 | 883 |
882 media::LogCB mse_log_cb; | 884 media::LogCB mse_log_cb; |
883 media::Demuxer::NeedKeyCB need_key_cb = | 885 media::Demuxer::NeedKeyCB need_key_cb = |
884 encrypted_media_support_->CreateNeedKeyCB(); | 886 encrypted_media_support_->CreateNeedKeyCB(); |
885 | 887 |
886 // Figure out which demuxer to use. | 888 // Figure out which demuxer to use. |
887 if (load_type_ != LoadTypeMediaSource) { | 889 if (load_type_ != LoadTypeMediaSource) { |
888 DCHECK(!chunk_demuxer_); | 890 DCHECK(!chunk_demuxer_); |
889 DCHECK(data_source_); | 891 DCHECK(data_source_); |
890 | 892 |
891 demuxer_.reset(new media::FFmpegDemuxer( | 893 demuxer_.reset(new media::FFmpegDemuxer( |
892 media_loop_, data_source_.get(), | 894 media_task_runner_, data_source_.get(), |
893 need_key_cb, | 895 need_key_cb, |
894 media_log_)); | 896 media_log_)); |
895 } else { | 897 } else { |
896 DCHECK(!chunk_demuxer_); | 898 DCHECK(!chunk_demuxer_); |
897 DCHECK(!data_source_); | 899 DCHECK(!data_source_); |
898 | 900 |
899 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_); | 901 mse_log_cb = base::Bind(&LogMediaSourceError, media_log_); |
900 | 902 |
901 chunk_demuxer_ = new media::ChunkDemuxer( | 903 chunk_demuxer_ = new media::ChunkDemuxer( |
902 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), | 904 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDemuxerOpened), |
903 need_key_cb, | 905 need_key_cb, |
904 mse_log_cb, | 906 mse_log_cb, |
905 true); | 907 true); |
906 demuxer_.reset(chunk_demuxer_); | 908 demuxer_.reset(chunk_demuxer_); |
907 } | 909 } |
908 | 910 |
909 scoped_ptr<media::FilterCollection> filter_collection( | 911 scoped_ptr<media::FilterCollection> filter_collection( |
910 new media::FilterCollection()); | 912 new media::FilterCollection()); |
911 filter_collection->SetDemuxer(demuxer_.get()); | 913 filter_collection->SetDemuxer(demuxer_.get()); |
912 filter_collection->SetRenderer(CreateRenderer()); | 914 filter_collection->SetRenderer(CreateRenderer()); |
913 | 915 |
914 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { | 916 if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { |
915 scoped_ptr<media::TextRenderer> text_renderer( | 917 scoped_ptr<media::TextRenderer> text_renderer( |
916 new media::TextRenderer( | 918 new media::TextRenderer( |
917 media_loop_, | 919 media_task_runner_, |
918 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); | 920 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnAddTextTrack))); |
919 | 921 |
920 filter_collection->SetTextRenderer(text_renderer.Pass()); | 922 filter_collection->SetTextRenderer(text_renderer.Pass()); |
921 } | 923 } |
922 | 924 |
923 // ... and we're ready to go! | 925 // ... and we're ready to go! |
924 seeking_ = true; | 926 seeking_ = true; |
925 pipeline_.Start( | 927 pipeline_.Start( |
926 filter_collection.Pass(), | 928 filter_collection.Pass(), |
927 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), | 929 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineEnded), |
928 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), | 930 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineError), |
929 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false), | 931 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, false), |
930 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), | 932 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineMetadata), |
931 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), | 933 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnPipelineBufferingStateChanged), |
932 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged)); | 934 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnDurationChanged)); |
933 } | 935 } |
934 | 936 |
935 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { | 937 void WebMediaPlayerImpl::SetNetworkState(WebMediaPlayer::NetworkState state) { |
936 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 938 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
937 DCHECK(main_loop_->BelongsToCurrentThread()); | 939 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
938 network_state_ = state; | 940 network_state_ = state; |
939 // Always notify to ensure client has the latest value. | 941 // Always notify to ensure client has the latest value. |
940 client_->networkStateChanged(); | 942 client_->networkStateChanged(); |
941 } | 943 } |
942 | 944 |
943 void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { | 945 void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { |
944 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; | 946 DVLOG(1) << __FUNCTION__ << "(" << state << ")"; |
945 DCHECK(main_loop_->BelongsToCurrentThread()); | 947 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
946 | 948 |
947 if (state == WebMediaPlayer::ReadyStateHaveEnoughData && data_source_ && | 949 if (state == WebMediaPlayer::ReadyStateHaveEnoughData && data_source_ && |
948 data_source_->assume_fully_buffered() && | 950 data_source_->assume_fully_buffered() && |
949 network_state_ == WebMediaPlayer::NetworkStateLoading) | 951 network_state_ == WebMediaPlayer::NetworkStateLoading) |
950 SetNetworkState(WebMediaPlayer::NetworkStateLoaded); | 952 SetNetworkState(WebMediaPlayer::NetworkStateLoaded); |
951 | 953 |
952 ready_state_ = state; | 954 ready_state_ = state; |
953 // Always notify to ensure client has the latest value. | 955 // Always notify to ensure client has the latest value. |
954 client_->readyStateChanged(); | 956 client_->readyStateChanged(); |
955 } | 957 } |
(...skipping 14 matching lines...) Expand all Loading... |
970 } | 972 } |
971 | 973 |
972 void WebMediaPlayerImpl::OnDurationChanged() { | 974 void WebMediaPlayerImpl::OnDurationChanged() { |
973 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 975 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
974 return; | 976 return; |
975 | 977 |
976 client_->durationChanged(); | 978 client_->durationChanged(); |
977 } | 979 } |
978 | 980 |
979 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { | 981 void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
980 DCHECK(main_loop_->BelongsToCurrentThread()); | 982 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
981 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 983 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
982 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); | 984 TRACE_EVENT0("media", "WebMediaPlayerImpl::OnNaturalSizeChanged"); |
983 | 985 |
984 media_log_->AddEvent( | 986 media_log_->AddEvent( |
985 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); | 987 media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
986 pipeline_metadata_.natural_size = size; | 988 pipeline_metadata_.natural_size = size; |
987 | 989 |
988 client_->sizeChanged(); | 990 client_->sizeChanged(); |
989 } | 991 } |
990 | 992 |
991 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { | 993 void WebMediaPlayerImpl::OnOpacityChanged(bool opaque) { |
992 DCHECK(main_loop_->BelongsToCurrentThread()); | 994 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
993 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 995 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
994 | 996 |
995 opaque_ = opaque; | 997 opaque_ = opaque; |
996 if (video_weblayer_) | 998 if (video_weblayer_) |
997 video_weblayer_->setOpaque(opaque_); | 999 video_weblayer_->setOpaque(opaque_); |
998 } | 1000 } |
999 | 1001 |
1000 void WebMediaPlayerImpl::FrameReady( | 1002 void WebMediaPlayerImpl::FrameReady( |
1001 const scoped_refptr<media::VideoFrame>& frame) { | 1003 const scoped_refptr<media::VideoFrame>& frame) { |
1002 compositor_task_runner_->PostTask( | 1004 compositor_task_runner_->PostTask( |
(...skipping 25 matching lines...) Expand all Loading... |
1028 compositor_task_runner_->PostTask(FROM_HERE, | 1030 compositor_task_runner_->PostTask(FROM_HERE, |
1029 base::Bind(&GetCurrentFrameAndSignal, | 1031 base::Bind(&GetCurrentFrameAndSignal, |
1030 base::Unretained(compositor_), | 1032 base::Unretained(compositor_), |
1031 &video_frame, | 1033 &video_frame, |
1032 &event)); | 1034 &event)); |
1033 event.Wait(); | 1035 event.Wait(); |
1034 return video_frame; | 1036 return video_frame; |
1035 } | 1037 } |
1036 | 1038 |
1037 } // namespace content | 1039 } // namespace content |
OLD | NEW |