Chromium Code Reviews| 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> |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 145 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
| 146 const WebMediaPlayerParams& params) | 146 const WebMediaPlayerParams& params) |
| 147 : frame_(frame), | 147 : frame_(frame), |
| 148 network_state_(WebMediaPlayer::NetworkStateEmpty), | 148 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 149 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 149 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 150 main_loop_(base::MessageLoopProxy::current()), | 150 main_loop_(base::MessageLoopProxy::current()), |
| 151 media_loop_( | 151 media_loop_( |
| 152 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), | 152 RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), |
| 153 media_log_(new RenderMediaLog()), | 153 media_log_(new RenderMediaLog()), |
| 154 pipeline_(media_loop_, media_log_.get()), | 154 pipeline_(media_loop_, media_log_.get()), |
| 155 total_bytes_(0), | |
| 156 did_loading_progress_(false), | |
| 155 paused_(true), | 157 paused_(true), |
| 156 seeking_(false), | 158 seeking_(false), |
| 157 playback_rate_(0.0f), | 159 playback_rate_(0.0f), |
| 158 pending_seek_(false), | 160 pending_seek_(false), |
| 159 pending_seek_seconds_(0.0f), | 161 pending_seek_seconds_(0.0f), |
| 160 client_(client), | 162 client_(client), |
| 161 delegate_(delegate), | 163 delegate_(delegate), |
| 162 defer_load_cb_(params.defer_load_cb()), | 164 defer_load_cb_(params.defer_load_cb()), |
| 163 accelerated_compositing_reported_(false), | 165 accelerated_compositing_reported_(false), |
| 164 incremented_externally_allocated_memory_(false), | 166 incremented_externally_allocated_memory_(false), |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); | 303 media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); |
| 302 | 304 |
| 303 // Media source pipelines can start immediately. | 305 // Media source pipelines can start immediately. |
| 304 if (load_type == LoadTypeMediaSource) { | 306 if (load_type == LoadTypeMediaSource) { |
| 305 supports_save_ = false; | 307 supports_save_ = false; |
| 306 StartPipeline(); | 308 StartPipeline(); |
| 307 return; | 309 return; |
| 308 } | 310 } |
| 309 | 311 |
| 310 // Otherwise it's a regular request which requires resolving the URL first. | 312 // Otherwise it's a regular request which requires resolving the URL first. |
| 311 // TODO(sandersd): Make WMPI a DataSourceHost and pass |this| instead of | |
| 312 // |&pipeline_|. | |
| 313 data_source_.reset(new BufferedDataSource( | 313 data_source_.reset(new BufferedDataSource( |
| 314 main_loop_, | 314 main_loop_, |
| 315 frame_, | 315 frame_, |
| 316 media_log_.get(), | 316 media_log_.get(), |
| 317 &pipeline_, | 317 this, |
| 318 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 318 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
| 319 data_source_->Initialize( | 319 data_source_->Initialize( |
| 320 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 320 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
| 321 base::Bind( | 321 base::Bind( |
| 322 &WebMediaPlayerImpl::DataSourceInitialized, | 322 &WebMediaPlayerImpl::DataSourceInitialized, |
| 323 AsWeakPtr(), gurl)); | 323 AsWeakPtr(), gurl)); |
| 324 | 324 |
| 325 is_local_source_ = !gurl.SchemeIsHTTPOrHTTPS(); | 325 is_local_source_ = !gurl.SchemeIsHTTPOrHTTPS(); |
| 326 } | 326 } |
| 327 | 327 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { | 488 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { |
| 489 DCHECK(main_loop_->BelongsToCurrentThread()); | 489 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 490 return network_state_; | 490 return network_state_; |
| 491 } | 491 } |
| 492 | 492 |
| 493 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { | 493 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { |
| 494 DCHECK(main_loop_->BelongsToCurrentThread()); | 494 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 495 return ready_state_; | 495 return ready_state_; |
| 496 } | 496 } |
| 497 | 497 |
| 498 namespace { | |
| 499 | |
| 500 base::TimeDelta TimeForByteOffset( | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
re: anon namespace vs. static ... try to go w/ con
sandersd (OOO until July 31)
2014/04/04 23:48:41
Done.
| |
| 501 int64 byte_offset, int64 total_bytes, base::TimeDelta duration) { | |
| 502 double position = static_cast<double>(byte_offset) / total_bytes; | |
| 503 // Snap to the beginning/end where the approximation can look especially bad. | |
| 504 if (position < 0.01) | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
this looks changed from the code in pipeline.cc --
sandersd (OOO until July 31)
2014/04/04 23:48:41
Computing and using an epsilon seemed needlessly c
| |
| 505 return base::TimeDelta(); | |
| 506 if (position > 0.99) | |
| 507 return duration; | |
| 508 return base::TimeDelta::FromMilliseconds( | |
| 509 static_cast<int64>(position * duration.InMilliseconds())); | |
| 510 } | |
| 511 | |
| 512 } | |
| 513 | |
| 498 const blink::WebTimeRanges& WebMediaPlayerImpl::buffered() { | 514 const blink::WebTimeRanges& WebMediaPlayerImpl::buffered() { |
| 499 DCHECK(main_loop_->BelongsToCurrentThread()); | 515 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 500 blink::WebTimeRanges web_ranges( | 516 media::Ranges<base::TimeDelta> buffered_time_ranges = |
| 501 ConvertToWebTimeRanges(pipeline_.GetBufferedTimeRanges())); | 517 pipeline_.GetBufferedTimeRanges(); |
| 502 buffered_.swap(web_ranges); | 518 if (total_bytes_ && buffered_byte_ranges_.size()) { |
|
scherkus (not reviewing)
2014/04/03 21:59:37
hmm... I wonder whether we can tighten up the BDSH
sandersd (OOO until July 31)
2014/04/04 23:48:41
It's possible to not know the total size of the so
| |
| 519 base::TimeDelta duration = pipeline_.GetMediaDuration(); | |
| 520 for (size_t i = 0; i < buffered_byte_ranges_.size(); ++i) { | |
| 521 int64 start = buffered_byte_ranges_.start(i); | |
| 522 int64 end = buffered_byte_ranges_.end(i); | |
| 523 buffered_time_ranges.Add(TimeForByteOffset(start, total_bytes_, duration), | |
| 524 TimeForByteOffset(end, total_bytes_, duration)); | |
| 525 } | |
| 526 } | |
| 527 // TODO(sandersd): Why return a reference at all? | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
see my explanation below -- it's probably because
sandersd (OOO until July 31)
2014/04/04 23:48:41
I've created a bug.
| |
| 528 blink::WebTimeRanges buffered = ConvertToWebTimeRanges(buffered_time_ranges); | |
| 529 buffered_.swap(buffered); | |
| 503 return buffered_; | 530 return buffered_; |
| 504 } | 531 } |
| 505 | 532 |
| 506 double WebMediaPlayerImpl::maxTimeSeekable() const { | 533 double WebMediaPlayerImpl::maxTimeSeekable() const { |
| 507 DCHECK(main_loop_->BelongsToCurrentThread()); | 534 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 508 | 535 |
| 509 // If we haven't even gotten to ReadyStateHaveMetadata yet then just | 536 // If we haven't even gotten to ReadyStateHaveMetadata yet then just |
| 510 // return 0 so that the seekable range is empty. | 537 // return 0 so that the seekable range is empty. |
| 511 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) | 538 if (ready_state_ < WebMediaPlayer::ReadyStateHaveMetadata) |
| 512 return 0.0; | 539 return 0.0; |
| 513 | 540 |
| 514 // We don't support seeking in streaming media. | 541 // We don't support seeking in streaming media. |
| 515 if (data_source_ && data_source_->IsStreaming()) | 542 if (data_source_ && data_source_->IsStreaming()) |
| 516 return 0.0; | 543 return 0.0; |
| 517 return duration(); | 544 return duration(); |
| 518 } | 545 } |
| 519 | 546 |
| 547 // TODO(sandersd): Why is this const!? | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
likely because const spreads and we used to share
sandersd (OOO until July 31)
2014/04/04 23:48:41
I created a bug and added a comment in WMPI.h.
| |
| 520 bool WebMediaPlayerImpl::didLoadingProgress() const { | 548 bool WebMediaPlayerImpl::didLoadingProgress() const { |
| 521 DCHECK(main_loop_->BelongsToCurrentThread()); | 549 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 522 | 550 bool merged = pipeline_.DidLoadingProgress() || did_loading_progress_; |
| 523 return pipeline_.DidLoadingProgress(); | 551 did_loading_progress_ = false; |
| 552 return merged; | |
| 524 } | 553 } |
| 525 | 554 |
| 526 void WebMediaPlayerImpl::paint(WebCanvas* canvas, | 555 void WebMediaPlayerImpl::paint(WebCanvas* canvas, |
| 527 const WebRect& rect, | 556 const WebRect& rect, |
| 528 unsigned char alpha) { | 557 unsigned char alpha) { |
| 529 DCHECK(main_loop_->BelongsToCurrentThread()); | 558 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 530 | 559 |
| 531 if (!accelerated_compositing_reported_) { | 560 if (!accelerated_compositing_reported_) { |
| 532 accelerated_compositing_reported_ = true; | 561 accelerated_compositing_reported_ = true; |
| 533 // Normally paint() is only called in non-accelerated rendering, but there | 562 // Normally paint() is only called in non-accelerated rendering, but there |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 898 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 | 927 // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 |
| 899 if (!cdm) | 928 if (!cdm) |
| 900 return; | 929 return; |
| 901 | 930 |
| 902 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); | 931 web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); |
| 903 | 932 |
| 904 if (web_cdm_ && !decryptor_ready_cb_.is_null()) | 933 if (web_cdm_ && !decryptor_ready_cb_.is_null()) |
| 905 base::ResetAndReturn(&decryptor_ready_cb_).Run(web_cdm_->GetDecryptor()); | 934 base::ResetAndReturn(&decryptor_ready_cb_).Run(web_cdm_->GetDecryptor()); |
| 906 } | 935 } |
| 907 | 936 |
| 937 void WebMediaPlayerImpl::SetTotalBytes(int64 total_bytes) { | |
| 938 DCHECK(main_loop_->BelongsToCurrentThread()); | |
| 939 TRACE_EVENT0("media", "WebMediaPlayerImpl::SetTotalBytes"); | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
no need to have trace macros here -- I don't see u
sandersd (OOO until July 31)
2014/04/04 23:48:41
Done.
| |
| 940 total_bytes_ = total_bytes; | |
| 941 } | |
| 942 | |
| 943 void WebMediaPlayerImpl::AddBufferedByteRange(int64 start, int64 end) { | |
| 944 DCHECK(main_loop_->BelongsToCurrentThread()); | |
| 945 TRACE_EVENT0("media", "WebMediaPlayerImpl::AddBufferedByteRange"); | |
|
scherkus (not reviewing)
2014/04/03 21:59:37
dittop
sandersd (OOO until July 31)
2014/04/04 23:48:41
Done.
| |
| 946 buffered_byte_ranges_.Add(start, end); | |
| 947 did_loading_progress_ = true; | |
| 948 } | |
| 949 | |
| 908 void WebMediaPlayerImpl::InvalidateOnMainThread() { | 950 void WebMediaPlayerImpl::InvalidateOnMainThread() { |
| 909 DCHECK(main_loop_->BelongsToCurrentThread()); | 951 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 910 TRACE_EVENT0("media", "WebMediaPlayerImpl::InvalidateOnMainThread"); | 952 TRACE_EVENT0("media", "WebMediaPlayerImpl::InvalidateOnMainThread"); |
| 911 | 953 |
| 912 client_->repaint(); | 954 client_->repaint(); |
| 913 } | 955 } |
| 914 | 956 |
| 915 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) { | 957 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) { |
| 916 DCHECK(main_loop_->BelongsToCurrentThread()); | 958 DCHECK(main_loop_->BelongsToCurrentThread()); |
| 917 starting_ = false; | 959 starting_ = false; |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1320 | 1362 |
| 1321 if (web_cdm_) { | 1363 if (web_cdm_) { |
| 1322 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); | 1364 decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); |
| 1323 return; | 1365 return; |
| 1324 } | 1366 } |
| 1325 | 1367 |
| 1326 decryptor_ready_cb_ = decryptor_ready_cb; | 1368 decryptor_ready_cb_ = decryptor_ready_cb; |
| 1327 } | 1369 } |
| 1328 | 1370 |
| 1329 } // namespace content | 1371 } // namespace content |
| OLD | NEW |