Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, | 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, |
| 6 // potential deadlocks, etc... | 6 // potential deadlocks, etc... |
| 7 | 7 |
| 8 #include "media/base/pipeline_impl.h" | 8 #include "media/base/pipeline_impl.h" |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 base::AutoLock auto_lock(lock_); | 177 base::AutoLock auto_lock(lock_); |
| 178 return has_video_; | 178 return has_video_; |
| 179 } | 179 } |
| 180 | 180 |
| 181 float PipelineImpl::GetPlaybackRate() const { | 181 float PipelineImpl::GetPlaybackRate() const { |
| 182 base::AutoLock auto_lock(lock_); | 182 base::AutoLock auto_lock(lock_); |
| 183 return playback_rate_; | 183 return playback_rate_; |
| 184 } | 184 } |
| 185 | 185 |
| 186 void PipelineImpl::SetPlaybackRate(float playback_rate) { | 186 void PipelineImpl::SetPlaybackRate(float playback_rate) { |
| 187 if (playback_rate < 0.0f) { | 187 if (playback_rate < 0.0f) |
| 188 return; | 188 return; |
| 189 } | |
| 190 | 189 |
| 191 base::AutoLock auto_lock(lock_); | 190 base::AutoLock auto_lock(lock_); |
| 192 playback_rate_ = playback_rate; | 191 playback_rate_ = playback_rate; |
| 193 if (running_ && !tearing_down_) { | 192 if (running_ && !tearing_down_) { |
| 194 message_loop_->PostTask(FROM_HERE, base::Bind( | 193 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 195 &PipelineImpl::PlaybackRateChangedTask, this, playback_rate)); | 194 &PipelineImpl::PlaybackRateChangedTask, this, playback_rate)); |
| 196 } | 195 } |
| 197 } | 196 } |
| 198 | 197 |
| 199 float PipelineImpl::GetVolume() const { | 198 float PipelineImpl::GetVolume() const { |
| 200 base::AutoLock auto_lock(lock_); | 199 base::AutoLock auto_lock(lock_); |
| 201 return volume_; | 200 return volume_; |
| 202 } | 201 } |
| 203 | 202 |
| 204 void PipelineImpl::SetVolume(float volume) { | 203 void PipelineImpl::SetVolume(float volume) { |
| 205 if (volume < 0.0f || volume > 1.0f) { | 204 if (volume < 0.0f || volume > 1.0f) |
| 206 return; | 205 return; |
| 207 } | |
| 208 | 206 |
| 209 base::AutoLock auto_lock(lock_); | 207 base::AutoLock auto_lock(lock_); |
| 210 volume_ = volume; | 208 volume_ = volume; |
| 211 if (running_ && !tearing_down_) { | 209 if (running_ && !tearing_down_) { |
| 212 message_loop_->PostTask(FROM_HERE, base::Bind( | 210 message_loop_->PostTask(FROM_HERE, base::Bind( |
| 213 &PipelineImpl::VolumeChangedTask, this, volume)); | 211 &PipelineImpl::VolumeChangedTask, this, volume)); |
| 214 } | 212 } |
| 215 } | 213 } |
| 216 | 214 |
| 217 Preload PipelineImpl::GetPreload() const { | 215 Preload PipelineImpl::GetPreload() const { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 230 | 228 |
| 231 base::TimeDelta PipelineImpl::GetCurrentTime() const { | 229 base::TimeDelta PipelineImpl::GetCurrentTime() const { |
| 232 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that | 230 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that |
| 233 // is set/get under the lock, because this is breaching the contract that | 231 // is set/get under the lock, because this is breaching the contract that |
| 234 // |state_| is only accessed on |message_loop_|. | 232 // |state_| is only accessed on |message_loop_|. |
| 235 base::AutoLock auto_lock(lock_); | 233 base::AutoLock auto_lock(lock_); |
| 236 return GetCurrentTime_Locked(); | 234 return GetCurrentTime_Locked(); |
| 237 } | 235 } |
| 238 | 236 |
| 239 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { | 237 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { |
| 238 lock_.AssertAcquired(); | |
| 240 base::TimeDelta elapsed = clock_->Elapsed(); | 239 base::TimeDelta elapsed = clock_->Elapsed(); |
| 241 if (state_ == kEnded || elapsed > duration_) { | 240 if (state_ == kEnded || elapsed > duration_) { |
| 242 return duration_; | 241 return duration_; |
| 243 } | 242 } |
| 244 return elapsed; | 243 return elapsed; |
| 245 } | 244 } |
| 246 | 245 |
| 247 base::TimeDelta PipelineImpl::GetBufferedTime() { | 246 base::TimeDelta PipelineImpl::GetBufferedTime() { |
| 248 base::AutoLock auto_lock(lock_); | 247 base::AutoLock auto_lock(lock_); |
| 248 return GetBufferedTime_Locked(); | |
| 249 } | |
| 249 | 250 |
| 251 base::TimeDelta PipelineImpl::GetBufferedTime_Locked() { | |
| 252 lock_.AssertAcquired(); | |
| 250 // If media is fully loaded, then return duration. | 253 // If media is fully loaded, then return duration. |
| 251 if (loaded_ || total_bytes_ == buffered_bytes_) { | 254 if (loaded_ || total_bytes_ == buffered_bytes_) { |
| 252 max_buffered_time_ = duration_; | 255 max_buffered_time_ = duration_; |
| 253 return duration_; | 256 return duration_; |
| 254 } | 257 } |
| 255 | 258 |
| 256 base::TimeDelta current_time = GetCurrentTime_Locked(); | 259 base::TimeDelta current_time = GetCurrentTime_Locked(); |
| 257 | 260 |
| 258 // If buffered time was set, we report that value directly. | 261 // If buffered time was set, we report that value directly. |
| 259 if (buffered_time_.ToInternalValue() > 0) { | 262 if (buffered_time_.ToInternalValue() > 0) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 volume_ = 1.0f; | 365 volume_ = 1.0f; |
| 363 preload_ = AUTO; | 366 preload_ = AUTO; |
| 364 playback_rate_ = 0.0f; | 367 playback_rate_ = 0.0f; |
| 365 pending_playback_rate_ = 0.0f; | 368 pending_playback_rate_ = 0.0f; |
| 366 status_ = PIPELINE_OK; | 369 status_ = PIPELINE_OK; |
| 367 has_audio_ = false; | 370 has_audio_ = false; |
| 368 has_video_ = false; | 371 has_video_ = false; |
| 369 waiting_for_clock_update_ = false; | 372 waiting_for_clock_update_ = false; |
| 370 audio_disabled_ = false; | 373 audio_disabled_ = false; |
| 371 clock_->SetTime(kZero); | 374 clock_->SetTime(kZero); |
| 375 starting_bytes_loaded_ = 0; | |
| 376 starting_time_ = base::Time(); | |
| 377 has_notified_can_play_through_ = false; | |
| 378 is_downloading_data_ = false; | |
| 379 last_approximate_download_rate_ = -1; | |
| 372 } | 380 } |
| 373 | 381 |
| 374 void PipelineImpl::SetState(State next_state) { | 382 void PipelineImpl::SetState(State next_state) { |
| 375 state_ = next_state; | 383 state_ = next_state; |
| 376 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); | 384 media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); |
| 377 } | 385 } |
| 378 | 386 |
| 379 bool PipelineImpl::IsPipelineOk() { | 387 bool PipelineImpl::IsPipelineOk() { |
| 380 base::AutoLock auto_lock(lock_); | 388 base::AutoLock auto_lock(lock_); |
| 381 return status_ == PIPELINE_OK; | 389 return status_ == PIPELINE_OK; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 407 } | 415 } |
| 408 | 416 |
| 409 void PipelineImpl::FinishInitialization() { | 417 void PipelineImpl::FinishInitialization() { |
| 410 DCHECK_EQ(MessageLoop::current(), message_loop_); | 418 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 411 // Execute the seek callback, if present. Note that this might be the | 419 // Execute the seek callback, if present. Note that this might be the |
| 412 // initial callback passed into Start(). | 420 // initial callback passed into Start(). |
| 413 if (!seek_callback_.is_null()) { | 421 if (!seek_callback_.is_null()) { |
| 414 seek_callback_.Run(status_); | 422 seek_callback_.Run(status_); |
| 415 seek_callback_.Reset(); | 423 seek_callback_.Reset(); |
| 416 } | 424 } |
| 425 is_downloading_data_ = true; | |
| 426 starting_time_ = base::Time::Now(); | |
| 427 NotifyCanPlayThroughIfNeeded(); | |
| 417 } | 428 } |
| 418 | 429 |
| 419 // static | 430 // static |
| 420 bool PipelineImpl::TransientState(State state) { | 431 bool PipelineImpl::TransientState(State state) { |
| 421 return state == kPausing || | 432 return state == kPausing || |
| 422 state == kFlushing || | 433 state == kFlushing || |
| 423 state == kSeeking || | 434 state == kSeeking || |
| 424 state == kStarting || | 435 state == kStarting || |
| 425 state == kStopping; | 436 state == kStopping; |
| 426 } | 437 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 media_log_->AddEvent( | 518 media_log_->AddEvent( |
| 508 media_log_->CreateIntegerEvent( | 519 media_log_->CreateIntegerEvent( |
| 509 MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); | 520 MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); |
| 510 | 521 |
| 511 base::AutoLock auto_lock(lock_); | 522 base::AutoLock auto_lock(lock_); |
| 512 total_bytes_ = total_bytes; | 523 total_bytes_ = total_bytes; |
| 513 } | 524 } |
| 514 | 525 |
| 515 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { | 526 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { |
| 516 DCHECK(IsRunning()); | 527 DCHECK(IsRunning()); |
| 517 base::AutoLock auto_lock(lock_); | 528 { |
| 518 | 529 base::AutoLock auto_lock(lock_); |
| 519 // See comments in SetCurrentReadPosition() about capping. | 530 // See comments in SetCurrentReadPosition() about capping. |
| 520 if (buffered_bytes < current_bytes_) | 531 if (buffered_bytes < current_bytes_) |
| 521 current_bytes_ = buffered_bytes; | 532 current_bytes_ = buffered_bytes; |
| 522 buffered_bytes_ = buffered_bytes; | 533 buffered_bytes_ = buffered_bytes; |
| 534 } | |
| 535 NotifyCanPlayThroughIfNeeded(); | |
| 523 } | 536 } |
| 524 | 537 |
| 525 void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { | 538 void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { |
| 526 DCHECK(IsRunning()); | 539 DCHECK(IsRunning()); |
| 527 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( | 540 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( |
| 528 size.width(), size.height())); | 541 size.width(), size.height())); |
| 529 | 542 |
| 530 base::AutoLock auto_lock(lock_); | 543 base::AutoLock auto_lock(lock_); |
| 531 natural_size_ = size; | 544 natural_size_ = size; |
| 532 } | 545 } |
| 533 | 546 |
| 534 void PipelineImpl::SetStreaming(bool streaming) { | 547 void PipelineImpl::SetStreaming(bool streaming) { |
| 535 DCHECK(IsRunning()); | 548 DCHECK(IsRunning()); |
| 536 media_log_->AddEvent( | 549 media_log_->AddEvent( |
| 537 media_log_->CreateBooleanEvent( | 550 media_log_->CreateBooleanEvent( |
| 538 MediaLogEvent::STREAMING_SET, "streaming", streaming)); | 551 MediaLogEvent::STREAMING_SET, "streaming", streaming)); |
| 539 | 552 |
| 540 base::AutoLock auto_lock(lock_); | 553 base::AutoLock auto_lock(lock_); |
| 541 streaming_ = streaming; | 554 streaming_ = streaming; |
| 542 } | 555 } |
| 543 | 556 |
| 544 void PipelineImpl::NotifyEnded() { | 557 void PipelineImpl::NotifyEnded() { |
| 545 DCHECK(IsRunning()); | 558 DCHECK(IsRunning()); |
| 546 message_loop_->PostTask(FROM_HERE, | 559 message_loop_->PostTask(FROM_HERE, |
| 547 base::Bind(&PipelineImpl::NotifyEndedTask, this)); | 560 base::Bind(&PipelineImpl::NotifyEndedTask, this)); |
| 548 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 561 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); |
| 562 NotifyCanPlayThroughIfNeeded(); | |
| 549 } | 563 } |
| 550 | 564 |
| 551 void PipelineImpl::SetLoaded(bool loaded) { | 565 void PipelineImpl::SetLoaded(bool loaded) { |
| 552 DCHECK(IsRunning()); | 566 DCHECK(IsRunning()); |
| 553 media_log_->AddEvent( | 567 media_log_->AddEvent( |
| 554 media_log_->CreateBooleanEvent( | 568 media_log_->CreateBooleanEvent( |
| 555 MediaLogEvent::LOADED_SET, "loaded", loaded)); | 569 MediaLogEvent::LOADED_SET, "loaded", loaded)); |
| 556 | 570 |
| 557 base::AutoLock auto_lock(lock_); | 571 base::AutoLock auto_lock(lock_); |
| 558 loaded_ = loaded; | 572 loaded_ = loaded; |
| 559 } | 573 } |
| 560 | 574 |
| 561 void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { | 575 void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { |
| 562 DCHECK(IsRunning()); | 576 DCHECK(IsRunning()); |
| 577 | |
| 578 base::AutoLock auto_lock(lock_); | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Why are we doing these operations here instead of
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Hmm, no real reason; I guess I was doing this here
| |
| 579 if (is_downloading_data_ == is_downloading_data) | |
| 580 return; | |
| 581 | |
| 582 is_downloading_data_ = is_downloading_data; | |
| 583 NetworkEvent type = DOWNLOAD_PAUSED; | |
| 584 if (is_downloading_data) { | |
| 585 type = DOWNLOAD_CONTINUED; | |
| 586 // Reset CanPlayThrough-related state when downloading continues. | |
| 587 starting_bytes_loaded_ = buffered_bytes_; | |
| 588 starting_time_ = base::Time::Now(); | |
| 589 } | |
| 563 message_loop_->PostTask(FROM_HERE, | 590 message_loop_->PostTask(FROM_HERE, |
| 564 base::Bind( | 591 base::Bind( |
| 565 &PipelineImpl::NotifyNetworkEventTask, this, is_downloading_data)); | 592 &PipelineImpl::NotifyNetworkEventTask, this, type)); |
| 566 media_log_->AddEvent( | 593 media_log_->AddEvent( |
| 567 media_log_->CreateBooleanEvent( | 594 media_log_->CreateBooleanEvent( |
| 568 MediaLogEvent::NETWORK_ACTIVITY_SET, | 595 MediaLogEvent::NETWORK_ACTIVITY_SET, |
| 569 "is_downloading_data", is_downloading_data)); | 596 "is_downloading_data", is_downloading_data)); |
| 570 } | 597 } |
| 571 | 598 |
| 572 void PipelineImpl::DisableAudioRenderer() { | 599 void PipelineImpl::DisableAudioRenderer() { |
| 573 DCHECK(IsRunning()); | 600 DCHECK(IsRunning()); |
| 574 | 601 |
| 575 // Disable renderer on the message loop. | 602 // Disable renderer on the message loop. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 // If we have received the stop or error signal, return immediately. | 688 // If we have received the stop or error signal, return immediately. |
| 662 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) | 689 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) |
| 663 return; | 690 return; |
| 664 | 691 |
| 665 DCHECK(state_ == kInitDemuxer || | 692 DCHECK(state_ == kInitDemuxer || |
| 666 state_ == kInitAudioDecoder || | 693 state_ == kInitAudioDecoder || |
| 667 state_ == kInitAudioRenderer || | 694 state_ == kInitAudioRenderer || |
| 668 state_ == kInitVideoDecoder || | 695 state_ == kInitVideoDecoder || |
| 669 state_ == kInitVideoRenderer); | 696 state_ == kInitVideoRenderer); |
| 670 | 697 |
| 671 | |
| 672 // Demuxer created, create audio decoder. | 698 // Demuxer created, create audio decoder. |
| 673 if (state_ == kInitDemuxer) { | 699 if (state_ == kInitDemuxer) { |
| 674 SetState(kInitAudioDecoder); | 700 SetState(kInitAudioDecoder); |
| 675 // If this method returns false, then there's no audio stream. | 701 // If this method returns false, then there's no audio stream. |
| 676 if (InitializeAudioDecoder(demuxer_)) | 702 if (InitializeAudioDecoder(demuxer_)) |
| 677 return; | 703 return; |
| 678 } | 704 } |
| 679 | 705 |
| 680 // Assuming audio decoder was created, create audio renderer. | 706 // Assuming audio decoder was created, create audio renderer. |
| 681 if (state_ == kInitAudioDecoder) { | 707 if (state_ == kInitAudioDecoder) { |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 919 return; | 945 return; |
| 920 } | 946 } |
| 921 | 947 |
| 922 // Transition to ended, executing the callback if present. | 948 // Transition to ended, executing the callback if present. |
| 923 SetState(kEnded); | 949 SetState(kEnded); |
| 924 if (!ended_callback_.is_null()) { | 950 if (!ended_callback_.is_null()) { |
| 925 ended_callback_.Run(status_); | 951 ended_callback_.Run(status_); |
| 926 } | 952 } |
| 927 } | 953 } |
| 928 | 954 |
| 929 void PipelineImpl::NotifyNetworkEventTask(bool is_downloading_data) { | 955 void PipelineImpl::NotifyNetworkEventTask(NetworkEvent type) { |
| 930 DCHECK_EQ(MessageLoop::current(), message_loop_); | 956 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 931 if (!network_callback_.is_null()) | 957 if (!network_callback_.is_null()) |
| 932 network_callback_.Run(is_downloading_data); | 958 network_callback_.Run(type); |
| 933 } | 959 } |
| 934 | 960 |
| 935 void PipelineImpl::DisableAudioRendererTask() { | 961 void PipelineImpl::DisableAudioRendererTask() { |
| 936 DCHECK_EQ(MessageLoop::current(), message_loop_); | 962 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 937 | 963 |
| 938 base::AutoLock auto_lock(lock_); | 964 base::AutoLock auto_lock(lock_); |
| 939 has_audio_ = false; | 965 has_audio_ = false; |
| 940 audio_disabled_ = true; | 966 audio_disabled_ = true; |
| 941 | 967 |
| 942 // Notify all filters of disabled audio renderer. If the filter isn't | 968 // Notify all filters of disabled audio renderer. If the filter isn't |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1368 base::Bind(&PipelineImpl::OnFilterStateTransitionWithStatus, this); | 1394 base::Bind(&PipelineImpl::OnFilterStateTransitionWithStatus, this); |
| 1369 | 1395 |
| 1370 if (status == PIPELINE_OK && pipeline_filter_) { | 1396 if (status == PIPELINE_OK && pipeline_filter_) { |
| 1371 pipeline_filter_->Seek(seek_timestamp, done_cb); | 1397 pipeline_filter_->Seek(seek_timestamp, done_cb); |
| 1372 return; | 1398 return; |
| 1373 } | 1399 } |
| 1374 | 1400 |
| 1375 done_cb.Run(status); | 1401 done_cb.Run(status); |
| 1376 } | 1402 } |
| 1377 | 1403 |
| 1404 void PipelineImpl::NotifyCanPlayThroughIfNeeded() { | |
| 1405 if (!IsRunning() || !IsInitialized()) | |
| 1406 return; | |
| 1407 | |
| 1408 base::AutoLock auto_lock(lock_); | |
| 1409 if (!ShouldNotifyCanPlayThrough_Locked()) | |
| 1410 return; | |
| 1411 | |
| 1412 has_notified_can_play_through_ = true; | |
| 1413 message_loop_->PostTask(FROM_HERE, | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Do we need this PostTask? Aren't we always on the
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
I believe we are not on this thread for 2 out of 3
| |
| 1414 base::Bind( | |
| 1415 &PipelineImpl::NotifyNetworkEventTask, this, CAN_PLAY_THROUGH)); | |
| 1416 } | |
| 1417 | |
| 1418 int PipelineImpl::ApproximateDownloadRate_Locked() { | |
| 1419 lock_.AssertAcquired(); | |
| 1420 | |
| 1421 // Playback hasn't started yet. | |
| 1422 if (starting_time_.is_null()) | |
| 1423 return -1; | |
| 1424 | |
| 1425 float seconds_elapsed = (base::Time::Now() - starting_time_).InSecondsF(); | |
| 1426 DCHECK(seconds_elapsed >= 0); | |
| 1427 // Update approximation if pipeline is downloading data and has been | |
| 1428 // downloading data long enough to get an accurate estimate. | |
| 1429 // XXX: How many seconds should we wait to get an accurate reading? | |
| 1430 if (is_downloading_data_ && seconds_elapsed > 1) { | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Make the time elapsed threshold a constant and let
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Done.
| |
| 1431 int bytes_downloaded = buffered_bytes_ - starting_bytes_loaded_; | |
| 1432 DCHECK(bytes_downloaded > 0); | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Should this really be a DCHECK? Shouldn't we just
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Oops, the ">" was meant to be a ">=". Am fine with
| |
| 1433 last_approximate_download_rate_ = bytes_downloaded / seconds_elapsed; | |
| 1434 } | |
| 1435 return last_approximate_download_rate_; | |
| 1436 } | |
| 1437 | |
| 1438 bool PipelineImpl::ShouldNotifyCanPlayThrough_Locked() { | |
| 1439 lock_.AssertAcquired(); | |
| 1440 if (has_notified_can_play_through_ || total_bytes_ == 0) | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Might want to add a comment explaining what total_
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Done.
| |
| 1441 return false; | |
| 1442 if (loaded_ || buffered_bytes_ == total_bytes_) | |
| 1443 return true; | |
| 1444 | |
| 1445 int download_rate = ApproximateDownloadRate_Locked(); | |
| 1446 // If download rate is unknown, cannot approximate when the media can play | |
| 1447 // through. | |
| 1448 if (download_rate == -1) | |
| 1449 return false; | |
| 1450 | |
| 1451 // If we are downloading at or faster than the media's bitrate, then we can | |
| 1452 // play through to the end of the media without stopping to buffer. | |
| 1453 int bitrate = demuxer_->GetBitrate(); | |
| 1454 if (download_rate > bitrate * 8) | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
Shouldn't this be (8 * download_rate > bitrate) or
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
D'OH! Yes, absolutely. Done.
| |
| 1455 return true; | |
| 1456 | |
| 1457 // If the rate of downloading the media is slower than the rate at which the | |
| 1458 // media is being played back, see if there's enough data buffered to let the | |
| 1459 // media play through until the end without buffering. | |
| 1460 base::TimeDelta current_time = GetCurrentTime_Locked(); | |
| 1461 base::TimeDelta buffered_time = GetBufferedTime_Locked(); | |
| 1462 DCHECK(buffered_time >= current_time); | |
| 1463 float seconds_buffered = (buffered_time - current_time).InSecondsF(); | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
std::max(..., 0) to protect the computation in rel
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Done.
| |
| 1464 int bytes_downloaded_after_buffer_is_consumed = | |
|
acolwell GONE FROM CHROMIUM
2011/10/28 18:24:13
s/after/while/ ?
vrk (LEFT CHROMIUM)
2011/11/01 21:57:34
Done.
| |
| 1465 static_cast<int>(seconds_buffered * download_rate); | |
| 1466 int bytes_left_to_download = total_bytes_ - buffered_bytes_; | |
| 1467 | |
| 1468 return bytes_downloaded_after_buffer_is_consumed >= bytes_left_to_download; | |
| 1469 } | |
| 1470 | |
| 1378 } // namespace media | 1471 } // namespace media |
| OLD | NEW |