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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 base::AutoLock auto_lock(lock_); | 179 base::AutoLock auto_lock(lock_); |
180 return has_video_; | 180 return has_video_; |
181 } | 181 } |
182 | 182 |
183 float PipelineImpl::GetPlaybackRate() const { | 183 float PipelineImpl::GetPlaybackRate() const { |
184 base::AutoLock auto_lock(lock_); | 184 base::AutoLock auto_lock(lock_); |
185 return playback_rate_; | 185 return playback_rate_; |
186 } | 186 } |
187 | 187 |
188 void PipelineImpl::SetPlaybackRate(float playback_rate) { | 188 void PipelineImpl::SetPlaybackRate(float playback_rate) { |
189 if (playback_rate < 0.0f) { | 189 if (playback_rate < 0.0f) |
190 return; | 190 return; |
191 } | |
192 | 191 |
193 base::AutoLock auto_lock(lock_); | 192 base::AutoLock auto_lock(lock_); |
194 playback_rate_ = playback_rate; | 193 playback_rate_ = playback_rate; |
195 if (running_ && !tearing_down_) { | 194 if (running_ && !tearing_down_) { |
196 message_loop_->PostTask(FROM_HERE, base::Bind( | 195 message_loop_->PostTask(FROM_HERE, base::Bind( |
197 &PipelineImpl::PlaybackRateChangedTask, this, playback_rate)); | 196 &PipelineImpl::PlaybackRateChangedTask, this, playback_rate)); |
198 } | 197 } |
199 } | 198 } |
200 | 199 |
201 float PipelineImpl::GetVolume() const { | 200 float PipelineImpl::GetVolume() const { |
202 base::AutoLock auto_lock(lock_); | 201 base::AutoLock auto_lock(lock_); |
203 return volume_; | 202 return volume_; |
204 } | 203 } |
205 | 204 |
206 void PipelineImpl::SetVolume(float volume) { | 205 void PipelineImpl::SetVolume(float volume) { |
207 if (volume < 0.0f || volume > 1.0f) { | 206 if (volume < 0.0f || volume > 1.0f) |
208 return; | 207 return; |
209 } | |
210 | 208 |
211 base::AutoLock auto_lock(lock_); | 209 base::AutoLock auto_lock(lock_); |
212 volume_ = volume; | 210 volume_ = volume; |
213 if (running_ && !tearing_down_) { | 211 if (running_ && !tearing_down_) { |
214 message_loop_->PostTask(FROM_HERE, base::Bind( | 212 message_loop_->PostTask(FROM_HERE, base::Bind( |
215 &PipelineImpl::VolumeChangedTask, this, volume)); | 213 &PipelineImpl::VolumeChangedTask, this, volume)); |
216 } | 214 } |
217 } | 215 } |
218 | 216 |
219 Preload PipelineImpl::GetPreload() const { | 217 Preload PipelineImpl::GetPreload() const { |
(...skipping 12 matching lines...) Expand all Loading... | |
232 | 230 |
233 base::TimeDelta PipelineImpl::GetCurrentTime() const { | 231 base::TimeDelta PipelineImpl::GetCurrentTime() const { |
234 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that | 232 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that |
235 // is set/get under the lock, because this is breaching the contract that | 233 // is set/get under the lock, because this is breaching the contract that |
236 // |state_| is only accessed on |message_loop_|. | 234 // |state_| is only accessed on |message_loop_|. |
237 base::AutoLock auto_lock(lock_); | 235 base::AutoLock auto_lock(lock_); |
238 return GetCurrentTime_Locked(); | 236 return GetCurrentTime_Locked(); |
239 } | 237 } |
240 | 238 |
241 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { | 239 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { |
240 lock_.AssertAcquired(); | |
242 base::TimeDelta elapsed = clock_->Elapsed(); | 241 base::TimeDelta elapsed = clock_->Elapsed(); |
243 if (state_ == kEnded || elapsed > duration_) { | 242 if (state_ == kEnded || elapsed > duration_) { |
244 return duration_; | 243 return duration_; |
245 } | 244 } |
246 return elapsed; | 245 return elapsed; |
247 } | 246 } |
248 | 247 |
249 base::TimeDelta PipelineImpl::GetBufferedTime() { | 248 base::TimeDelta PipelineImpl::GetBufferedTime() { |
250 base::AutoLock auto_lock(lock_); | 249 base::AutoLock auto_lock(lock_); |
251 | 250 |
252 // If media is fully loaded, then return duration. | 251 // If media is fully loaded, then return duration. |
253 if (loaded_ || total_bytes_ == buffered_bytes_) { | 252 if (loaded_ || total_bytes_ == buffered_bytes_) { |
254 max_buffered_time_ = duration_; | 253 max_buffered_time_ = duration_; |
255 return duration_; | 254 return duration_; |
256 } | 255 } |
257 | 256 |
258 base::TimeDelta current_time = GetCurrentTime_Locked(); | 257 base::TimeDelta current_time = GetCurrentTime_Locked(); |
259 | 258 |
260 // If buffered time was set, we report that value directly. | 259 // If buffered time was set, we report that value directly. |
261 if (buffered_time_.ToInternalValue() > 0) { | 260 if (buffered_time_.ToInternalValue() > 0) |
262 return std::max(buffered_time_, current_time); | 261 return std::max(buffered_time_, current_time); |
263 } | |
264 | 262 |
265 if (total_bytes_ == 0) | 263 if (total_bytes_ == 0) |
266 return base::TimeDelta(); | 264 return base::TimeDelta(); |
267 | 265 |
268 // If buffered time was not set, we use current time, current bytes, and | 266 // If buffered time was not set, we use current time, current bytes, and |
269 // buffered bytes to estimate the buffered time. | 267 // buffered bytes to estimate the buffered time. |
270 double estimated_rate = duration_.InMillisecondsF() / total_bytes_; | 268 double estimated_rate = duration_.InMillisecondsF() / total_bytes_; |
271 double estimated_current_time = estimated_rate * current_bytes_; | 269 double estimated_current_time = estimated_rate * current_bytes_; |
272 DCHECK_GE(buffered_bytes_, current_bytes_); | 270 DCHECK_GE(buffered_bytes_, current_bytes_); |
273 base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds( | 271 base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds( |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 volume_ = 1.0f; | 362 volume_ = 1.0f; |
365 preload_ = AUTO; | 363 preload_ = AUTO; |
366 playback_rate_ = 0.0f; | 364 playback_rate_ = 0.0f; |
367 pending_playback_rate_ = 0.0f; | 365 pending_playback_rate_ = 0.0f; |
368 status_ = PIPELINE_OK; | 366 status_ = PIPELINE_OK; |
369 has_audio_ = false; | 367 has_audio_ = false; |
370 has_video_ = false; | 368 has_video_ = false; |
371 waiting_for_clock_update_ = false; | 369 waiting_for_clock_update_ = false; |
372 audio_disabled_ = false; | 370 audio_disabled_ = false; |
373 clock_->SetTime(kZero); | 371 clock_->SetTime(kZero); |
372 is_downloading_data_ = false; | |
acolwell GONE FROM CHROMIUM
2011/11/09 00:50:22
Does download_rate_monitor_ need to be reset here?
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
Yes, done.
| |
374 } | 373 } |
375 | 374 |
376 void PipelineImpl::SetState(State next_state) { | 375 void PipelineImpl::SetState(State next_state) { |
377 if (state_ != kStarted && next_state == kStarted && | 376 if (state_ != kStarted && next_state == kStarted && |
378 !creation_time_.is_null()) { | 377 !creation_time_.is_null()) { |
379 UMA_HISTOGRAM_TIMES( | 378 UMA_HISTOGRAM_TIMES( |
380 "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); | 379 "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); |
381 creation_time_ = base::Time(); | 380 creation_time_ = base::Time(); |
382 } | 381 } |
383 state_ = next_state; | 382 state_ = next_state; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 } | 414 } |
416 | 415 |
417 void PipelineImpl::FinishInitialization() { | 416 void PipelineImpl::FinishInitialization() { |
418 DCHECK_EQ(MessageLoop::current(), message_loop_); | 417 DCHECK_EQ(MessageLoop::current(), message_loop_); |
419 // Execute the seek callback, if present. Note that this might be the | 418 // Execute the seek callback, if present. Note that this might be the |
420 // initial callback passed into Start(). | 419 // initial callback passed into Start(). |
421 if (!seek_callback_.is_null()) { | 420 if (!seek_callback_.is_null()) { |
422 seek_callback_.Run(status_); | 421 seek_callback_.Run(status_); |
423 seek_callback_.Reset(); | 422 seek_callback_.Reset(); |
424 } | 423 } |
424 | |
425 base::AutoLock auto_lock(lock_); | |
acolwell GONE FROM CHROMIUM
2011/11/09 00:50:22
This is neaded because the SetXXXBytes() calls are
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
Actually the SetXXXBytes method calls (and SetLoad
| |
426 int bitrate = 0; | |
427 if (demuxer_.get()) | |
428 bitrate = demuxer_->GetBitrate(); | |
429 download_rate_monitor_.Start( | |
430 base::Bind(&PipelineImpl::OnCanPlayThrough, this), bitrate); | |
425 } | 431 } |
426 | 432 |
427 // static | 433 // static |
428 bool PipelineImpl::TransientState(State state) { | 434 bool PipelineImpl::TransientState(State state) { |
429 return state == kPausing || | 435 return state == kPausing || |
430 state == kFlushing || | 436 state == kFlushing || |
431 state == kSeeking || | 437 state == kSeeking || |
432 state == kStarting || | 438 state == kStarting || |
433 state == kStopping; | 439 state == kStopping; |
434 } | 440 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 media_log_->CreateIntegerEvent( | 523 media_log_->CreateIntegerEvent( |
518 MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); | 524 MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); |
519 int64 total_mbytes = total_bytes >> 20; | 525 int64 total_mbytes = total_bytes >> 20; |
520 if (total_mbytes > kint32max) | 526 if (total_mbytes > kint32max) |
521 total_mbytes = kint32max; | 527 total_mbytes = kint32max; |
522 UMA_HISTOGRAM_CUSTOM_COUNTS( | 528 UMA_HISTOGRAM_CUSTOM_COUNTS( |
523 "Media.TotalMBytes", static_cast<int32>(total_mbytes), 1, kint32max, 50); | 529 "Media.TotalMBytes", static_cast<int32>(total_mbytes), 1, kint32max, 50); |
524 | 530 |
525 base::AutoLock auto_lock(lock_); | 531 base::AutoLock auto_lock(lock_); |
526 total_bytes_ = total_bytes; | 532 total_bytes_ = total_bytes; |
533 download_rate_monitor_.SetTotalBytes(total_bytes_); | |
527 } | 534 } |
528 | 535 |
529 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { | 536 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { |
530 DCHECK(IsRunning()); | 537 DCHECK(IsRunning()); |
531 base::AutoLock auto_lock(lock_); | 538 base::AutoLock auto_lock(lock_); |
532 | |
533 // See comments in SetCurrentReadPosition() about capping. | 539 // See comments in SetCurrentReadPosition() about capping. |
534 if (buffered_bytes < current_bytes_) | 540 if (buffered_bytes < current_bytes_) |
535 current_bytes_ = buffered_bytes; | 541 current_bytes_ = buffered_bytes; |
536 buffered_bytes_ = buffered_bytes; | 542 buffered_bytes_ = buffered_bytes; |
543 download_rate_monitor_.SetBufferedBytes(buffered_bytes, base::Time::Now()); | |
537 } | 544 } |
538 | 545 |
539 void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { | 546 void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { |
540 DCHECK(IsRunning()); | 547 DCHECK(IsRunning()); |
541 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( | 548 media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( |
542 size.width(), size.height())); | 549 size.width(), size.height())); |
543 | 550 |
544 base::AutoLock auto_lock(lock_); | 551 base::AutoLock auto_lock(lock_); |
545 natural_size_ = size; | 552 natural_size_ = size; |
546 } | 553 } |
(...skipping 16 matching lines...) Expand all Loading... | |
563 } | 570 } |
564 | 571 |
565 void PipelineImpl::SetLoaded(bool loaded) { | 572 void PipelineImpl::SetLoaded(bool loaded) { |
566 DCHECK(IsRunning()); | 573 DCHECK(IsRunning()); |
567 media_log_->AddEvent( | 574 media_log_->AddEvent( |
568 media_log_->CreateBooleanEvent( | 575 media_log_->CreateBooleanEvent( |
569 MediaLogEvent::LOADED_SET, "loaded", loaded)); | 576 MediaLogEvent::LOADED_SET, "loaded", loaded)); |
570 | 577 |
571 base::AutoLock auto_lock(lock_); | 578 base::AutoLock auto_lock(lock_); |
572 loaded_ = loaded; | 579 loaded_ = loaded; |
580 download_rate_monitor_.SetLoaded(loaded_); | |
573 } | 581 } |
574 | 582 |
575 void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { | 583 void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { |
576 DCHECK(IsRunning()); | 584 DCHECK(IsRunning()); |
585 | |
586 NetworkEvent type = DOWNLOAD_PAUSED; | |
587 if (is_downloading_data) | |
588 type = DOWNLOAD_CONTINUED; | |
589 | |
590 { | |
591 base::AutoLock auto_lock(lock_); | |
592 download_rate_monitor_.SetNetworkActivity(is_downloading_data); | |
593 } | |
594 | |
577 message_loop_->PostTask(FROM_HERE, | 595 message_loop_->PostTask(FROM_HERE, |
578 base::Bind( | 596 base::Bind( |
579 &PipelineImpl::NotifyNetworkEventTask, this, is_downloading_data)); | 597 &PipelineImpl::NotifyNetworkEventTask, this, type, |
598 is_downloading_data)); | |
acolwell GONE FROM CHROMIUM
2011/11/09 00:50:22
Is is_downloading_data still needed given that it'
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
AH oops, you're right! It served a purpose when th
| |
580 media_log_->AddEvent( | 599 media_log_->AddEvent( |
581 media_log_->CreateBooleanEvent( | 600 media_log_->CreateBooleanEvent( |
582 MediaLogEvent::NETWORK_ACTIVITY_SET, | 601 MediaLogEvent::NETWORK_ACTIVITY_SET, |
583 "is_downloading_data", is_downloading_data)); | 602 "is_downloading_data", is_downloading_data)); |
584 } | 603 } |
585 | 604 |
586 void PipelineImpl::DisableAudioRenderer() { | 605 void PipelineImpl::DisableAudioRenderer() { |
587 DCHECK(IsRunning()); | 606 DCHECK(IsRunning()); |
588 | 607 |
589 // Disable renderer on the message loop. | 608 // Disable renderer on the message loop. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
675 // If we have received the stop or error signal, return immediately. | 694 // If we have received the stop or error signal, return immediately. |
676 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) | 695 if (IsPipelineStopPending() || IsPipelineStopped() || !IsPipelineOk()) |
677 return; | 696 return; |
678 | 697 |
679 DCHECK(state_ == kInitDemuxer || | 698 DCHECK(state_ == kInitDemuxer || |
680 state_ == kInitAudioDecoder || | 699 state_ == kInitAudioDecoder || |
681 state_ == kInitAudioRenderer || | 700 state_ == kInitAudioRenderer || |
682 state_ == kInitVideoDecoder || | 701 state_ == kInitVideoDecoder || |
683 state_ == kInitVideoRenderer); | 702 state_ == kInitVideoRenderer); |
684 | 703 |
685 | |
686 // Demuxer created, create audio decoder. | 704 // Demuxer created, create audio decoder. |
687 if (state_ == kInitDemuxer) { | 705 if (state_ == kInitDemuxer) { |
688 SetState(kInitAudioDecoder); | 706 SetState(kInitAudioDecoder); |
689 // If this method returns false, then there's no audio stream. | 707 // If this method returns false, then there's no audio stream. |
690 if (InitializeAudioDecoder(demuxer_)) | 708 if (InitializeAudioDecoder(demuxer_)) |
691 return; | 709 return; |
692 } | 710 } |
693 | 711 |
694 // Assuming audio decoder was created, create audio renderer. | 712 // Assuming audio decoder was created, create audio renderer. |
695 if (state_ == kInitAudioDecoder) { | 713 if (state_ == kInitAudioDecoder) { |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
933 return; | 951 return; |
934 } | 952 } |
935 | 953 |
936 // Transition to ended, executing the callback if present. | 954 // Transition to ended, executing the callback if present. |
937 SetState(kEnded); | 955 SetState(kEnded); |
938 if (!ended_callback_.is_null()) { | 956 if (!ended_callback_.is_null()) { |
939 ended_callback_.Run(status_); | 957 ended_callback_.Run(status_); |
940 } | 958 } |
941 } | 959 } |
942 | 960 |
943 void PipelineImpl::NotifyNetworkEventTask(bool is_downloading_data) { | 961 void PipelineImpl::NotifyNetworkEventTask(NetworkEvent type, |
962 bool is_downloading_data) { | |
944 DCHECK_EQ(MessageLoop::current(), message_loop_); | 963 DCHECK_EQ(MessageLoop::current(), message_loop_); |
964 is_downloading_data_ = is_downloading_data; | |
945 if (!network_callback_.is_null()) | 965 if (!network_callback_.is_null()) |
946 network_callback_.Run(is_downloading_data); | 966 network_callback_.Run(type); |
947 } | 967 } |
948 | 968 |
949 void PipelineImpl::DisableAudioRendererTask() { | 969 void PipelineImpl::DisableAudioRendererTask() { |
950 DCHECK_EQ(MessageLoop::current(), message_loop_); | 970 DCHECK_EQ(MessageLoop::current(), message_loop_); |
951 | 971 |
952 base::AutoLock auto_lock(lock_); | 972 base::AutoLock auto_lock(lock_); |
953 has_audio_ = false; | 973 has_audio_ = false; |
954 audio_disabled_ = true; | 974 audio_disabled_ = true; |
955 | 975 |
956 // Notify all filters of disabled audio renderer. If the filter isn't | 976 // Notify all filters of disabled audio renderer. If the filter isn't |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1398 return; | 1418 return; |
1399 } | 1419 } |
1400 | 1420 |
1401 if (state_ != kStarted) | 1421 if (state_ != kStarted) |
1402 return; | 1422 return; |
1403 | 1423 |
1404 if (audio_renderer_) | 1424 if (audio_renderer_) |
1405 audio_renderer_->ResumeAfterUnderflow(true); | 1425 audio_renderer_->ResumeAfterUnderflow(true); |
1406 } | 1426 } |
1407 | 1427 |
1428 void PipelineImpl::OnCanPlayThrough() { | |
1429 message_loop_->PostTask(FROM_HERE, | |
1430 base::Bind( | |
1431 &PipelineImpl::NotifyCanPlayThrough, this)); | |
scherkus (not reviewing)
2011/11/09 02:55:15
nit: can put this on previous line
vrk (LEFT CHROMIUM)
2011/11/11 02:51:06
Done.
| |
1432 } | |
1433 | |
1434 void PipelineImpl::NotifyCanPlayThrough() { | |
1435 DCHECK_EQ(MessageLoop::current(), message_loop_); | |
1436 NotifyNetworkEventTask(CAN_PLAY_THROUGH, is_downloading_data_); | |
1437 } | |
1438 | |
1408 } // namespace media | 1439 } // namespace media |
OLD | NEW |