| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "media/base/pipeline.h" | 5 #include "media/base/pipeline.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/bind.h" | 9 #include "base/bind.h" | 
| 10 #include "base/callback.h" | 10 #include "base/callback.h" | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 64   scoped_refptr<CompositeFilter> composite; | 64   scoped_refptr<CompositeFilter> composite; | 
| 65 }; | 65 }; | 
| 66 | 66 | 
| 67 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) | 67 Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) | 
| 68     : message_loop_(message_loop->message_loop_proxy()), | 68     : message_loop_(message_loop->message_loop_proxy()), | 
| 69       media_log_(media_log), | 69       media_log_(media_log), | 
| 70       clock_(new Clock(&base::Time::Now)), | 70       clock_(new Clock(&base::Time::Now)), | 
| 71       waiting_for_clock_update_(false), | 71       waiting_for_clock_update_(false), | 
| 72       state_(kCreated), | 72       state_(kCreated), | 
| 73       current_bytes_(0), | 73       current_bytes_(0), | 
| 74       creation_time_(base::Time::Now()), | 74       creation_time_(base::Time::Now()) { | 
| 75       is_downloading_data_(false) { |  | 
| 76   media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); | 75   media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated)); | 
| 77   ResetState(); | 76   ResetState(); | 
| 78   media_log_->AddEvent( | 77   media_log_->AddEvent( | 
| 79       media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); | 78       media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); | 
| 80 } | 79 } | 
| 81 | 80 | 
| 82 Pipeline::~Pipeline() { | 81 Pipeline::~Pipeline() { | 
| 83   base::AutoLock auto_lock(lock_); | 82   base::AutoLock auto_lock(lock_); | 
| 84   DCHECK(!running_) << "Stop() must complete before destroying object"; | 83   DCHECK(!running_) << "Stop() must complete before destroying object"; | 
| 85   DCHECK(!stop_pending_); | 84   DCHECK(!stop_pending_); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 110   // Stop the pipeline, which will set |running_| to false on our behalf. | 109   // Stop the pipeline, which will set |running_| to false on our behalf. | 
| 111   message_loop_->PostTask(FROM_HERE, base::Bind( | 110   message_loop_->PostTask(FROM_HERE, base::Bind( | 
| 112       &Pipeline::StopTask, this, stop_cb)); | 111       &Pipeline::StopTask, this, stop_cb)); | 
| 113 } | 112 } | 
| 114 | 113 | 
| 115 void Pipeline::Seek(base::TimeDelta time, | 114 void Pipeline::Seek(base::TimeDelta time, | 
| 116                     const PipelineStatusCB& seek_cb) { | 115                     const PipelineStatusCB& seek_cb) { | 
| 117   base::AutoLock auto_lock(lock_); | 116   base::AutoLock auto_lock(lock_); | 
| 118   CHECK(running_) << "Media pipeline isn't running"; | 117   CHECK(running_) << "Media pipeline isn't running"; | 
| 119 | 118 | 
| 120   download_rate_monitor_.Stop(); |  | 
| 121 |  | 
| 122   message_loop_->PostTask(FROM_HERE, base::Bind( | 119   message_loop_->PostTask(FROM_HERE, base::Bind( | 
| 123       &Pipeline::SeekTask, this, time, seek_cb)); | 120       &Pipeline::SeekTask, this, time, seek_cb)); | 
| 124 } | 121 } | 
| 125 | 122 | 
| 126 bool Pipeline::IsRunning() const { | 123 bool Pipeline::IsRunning() const { | 
| 127   base::AutoLock auto_lock(lock_); | 124   base::AutoLock auto_lock(lock_); | 
| 128   return running_; | 125   return running_; | 
| 129 } | 126 } | 
| 130 | 127 | 
| 131 bool Pipeline::IsInitialized() const { | 128 bool Pipeline::IsInitialized() const { | 
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 221 } | 218 } | 
| 222 | 219 | 
| 223 void Pipeline::GetNaturalVideoSize(gfx::Size* out_size) const { | 220 void Pipeline::GetNaturalVideoSize(gfx::Size* out_size) const { | 
| 224   CHECK(out_size); | 221   CHECK(out_size); | 
| 225   base::AutoLock auto_lock(lock_); | 222   base::AutoLock auto_lock(lock_); | 
| 226   *out_size = natural_size_; | 223   *out_size = natural_size_; | 
| 227 } | 224 } | 
| 228 | 225 | 
| 229 bool Pipeline::IsStreaming() const { | 226 bool Pipeline::IsStreaming() const { | 
| 230   base::AutoLock auto_lock(lock_); | 227   base::AutoLock auto_lock(lock_); | 
| 231   return streaming_; | 228   return demuxer_ && !demuxer_->IsSeekable(); | 
| 232 } | 229 } | 
| 233 | 230 | 
| 234 bool Pipeline::IsLocalSource() const { | 231 bool Pipeline::IsLocalSource() const { | 
| 235   base::AutoLock auto_lock(lock_); | 232   base::AutoLock auto_lock(lock_); | 
| 236   return local_source_; | 233   return demuxer_ && demuxer_->IsLocalSource(); | 
| 237 } | 234 } | 
| 238 | 235 | 
| 239 PipelineStatistics Pipeline::GetStatistics() const { | 236 PipelineStatistics Pipeline::GetStatistics() const { | 
| 240   base::AutoLock auto_lock(lock_); | 237   base::AutoLock auto_lock(lock_); | 
| 241   return statistics_; | 238   return statistics_; | 
| 242 } | 239 } | 
| 243 | 240 | 
| 244 void Pipeline::SetClockForTesting(Clock* clock) { | 241 void Pipeline::SetClockForTesting(Clock* clock) { | 
| 245   clock_.reset(clock); | 242   clock_.reset(clock); | 
| 246 } | 243 } | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 263   base::AutoLock auto_lock(lock_); | 260   base::AutoLock auto_lock(lock_); | 
| 264   const base::TimeDelta kZero; | 261   const base::TimeDelta kZero; | 
| 265   running_          = false; | 262   running_          = false; | 
| 266   stop_pending_     = false; | 263   stop_pending_     = false; | 
| 267   seek_pending_     = false; | 264   seek_pending_     = false; | 
| 268   tearing_down_     = false; | 265   tearing_down_     = false; | 
| 269   error_caused_teardown_ = false; | 266   error_caused_teardown_ = false; | 
| 270   playback_rate_change_pending_ = false; | 267   playback_rate_change_pending_ = false; | 
| 271   buffered_bytes_   = 0; | 268   buffered_bytes_   = 0; | 
| 272   buffered_time_ranges_.clear(); | 269   buffered_time_ranges_.clear(); | 
| 273   streaming_        = false; |  | 
| 274   local_source_     = false; |  | 
| 275   total_bytes_      = 0; | 270   total_bytes_      = 0; | 
| 276   natural_size_.SetSize(0, 0); | 271   natural_size_.SetSize(0, 0); | 
| 277   volume_           = 1.0f; | 272   volume_           = 1.0f; | 
| 278   playback_rate_    = 0.0f; | 273   playback_rate_    = 0.0f; | 
| 279   pending_playback_rate_ = 0.0f; | 274   pending_playback_rate_ = 0.0f; | 
| 280   status_           = PIPELINE_OK; | 275   status_           = PIPELINE_OK; | 
| 281   has_audio_        = false; | 276   has_audio_        = false; | 
| 282   has_video_        = false; | 277   has_video_        = false; | 
| 283   waiting_for_clock_update_ = false; | 278   waiting_for_clock_update_ = false; | 
| 284   audio_disabled_   = false; | 279   audio_disabled_   = false; | 
| 285   clock_->Reset(); | 280   clock_->Reset(); | 
| 286   download_rate_monitor_.Reset(); |  | 
| 287 } | 281 } | 
| 288 | 282 | 
| 289 void Pipeline::SetState(State next_state) { | 283 void Pipeline::SetState(State next_state) { | 
| 290   if (state_ != kStarted && next_state == kStarted && | 284   if (state_ != kStarted && next_state == kStarted && | 
| 291       !creation_time_.is_null()) { | 285       !creation_time_.is_null()) { | 
| 292     UMA_HISTOGRAM_TIMES( | 286     UMA_HISTOGRAM_TIMES( | 
| 293         "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); | 287         "Media.TimeToPipelineStarted", base::Time::Now() - creation_time_); | 
| 294     creation_time_ = base::Time(); | 288     creation_time_ = base::Time(); | 
| 295   } | 289   } | 
| 296   state_ = next_state; | 290   state_ = next_state; | 
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 445       media_log_->CreateIntegerEvent( | 439       media_log_->CreateIntegerEvent( | 
| 446           MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); | 440           MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", total_bytes)); | 
| 447   int64 total_mbytes = total_bytes >> 20; | 441   int64 total_mbytes = total_bytes >> 20; | 
| 448   if (total_mbytes > kint32max) | 442   if (total_mbytes > kint32max) | 
| 449     total_mbytes = kint32max; | 443     total_mbytes = kint32max; | 
| 450   UMA_HISTOGRAM_CUSTOM_COUNTS( | 444   UMA_HISTOGRAM_CUSTOM_COUNTS( | 
| 451       "Media.TotalMBytes", static_cast<int32>(total_mbytes), 1, kint32max, 50); | 445       "Media.TotalMBytes", static_cast<int32>(total_mbytes), 1, kint32max, 50); | 
| 452 | 446 | 
| 453   base::AutoLock auto_lock(lock_); | 447   base::AutoLock auto_lock(lock_); | 
| 454   total_bytes_ = total_bytes; | 448   total_bytes_ = total_bytes; | 
| 455   download_rate_monitor_.set_total_bytes(total_bytes_); |  | 
| 456 } | 449 } | 
| 457 | 450 | 
| 458 void Pipeline::SetBufferedBytes(int64 buffered_bytes) { | 451 void Pipeline::SetBufferedBytes(int64 buffered_bytes) { | 
| 459   DCHECK(IsRunning()); | 452   DCHECK(IsRunning()); | 
| 460   base::AutoLock auto_lock(lock_); | 453   base::AutoLock auto_lock(lock_); | 
| 461   // See comments in SetCurrentReadPosition() about capping. | 454   // See comments in SetCurrentReadPosition() about capping. | 
| 462   if (buffered_bytes < current_bytes_) | 455   if (buffered_bytes < current_bytes_) | 
| 463     current_bytes_ = buffered_bytes; | 456     current_bytes_ = buffered_bytes; | 
| 464   buffered_bytes_ = buffered_bytes; | 457   buffered_bytes_ = buffered_bytes; | 
| 465   download_rate_monitor_.SetBufferedBytes(buffered_bytes, base::Time::Now()); |  | 
| 466   UpdateBufferedTimeRanges_Locked(); | 458   UpdateBufferedTimeRanges_Locked(); | 
| 467 } | 459 } | 
| 468 | 460 | 
| 469 void Pipeline::UpdateBufferedTimeRanges_Locked() { | 461 void Pipeline::UpdateBufferedTimeRanges_Locked() { | 
| 470   lock_.AssertAcquired(); | 462   lock_.AssertAcquired(); | 
| 471   if (total_bytes_ == 0) | 463   if (total_bytes_ == 0) | 
| 472     return; | 464     return; | 
| 473   base::TimeDelta buffered_time = | 465   base::TimeDelta buffered_time = | 
| 474       clock_->Duration() * buffered_bytes_ / total_bytes_; | 466       clock_->Duration() * buffered_bytes_ / total_bytes_; | 
| 475   // Cap approximated buffered time at the length of the video. | 467   // Cap approximated buffered time at the length of the video. | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 497   media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 489   media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); | 
| 498 } | 490 } | 
| 499 | 491 | 
| 500 void Pipeline::SetNetworkActivity(bool is_downloading_data) { | 492 void Pipeline::SetNetworkActivity(bool is_downloading_data) { | 
| 501   DCHECK(IsRunning()); | 493   DCHECK(IsRunning()); | 
| 502 | 494 | 
| 503   NetworkEvent type = DOWNLOAD_PAUSED; | 495   NetworkEvent type = DOWNLOAD_PAUSED; | 
| 504   if (is_downloading_data) | 496   if (is_downloading_data) | 
| 505     type = DOWNLOAD_CONTINUED; | 497     type = DOWNLOAD_CONTINUED; | 
| 506 | 498 | 
| 507   { |  | 
| 508     base::AutoLock auto_lock(lock_); |  | 
| 509     download_rate_monitor_.SetNetworkActivity(is_downloading_data); |  | 
| 510   } |  | 
| 511 |  | 
| 512   message_loop_->PostTask(FROM_HERE, base::Bind( | 499   message_loop_->PostTask(FROM_HERE, base::Bind( | 
| 513       &Pipeline::NotifyNetworkEventTask, this, type)); | 500       &Pipeline::NotifyNetworkEventTask, this, type)); | 
| 514   media_log_->AddEvent( | 501   media_log_->AddEvent( | 
| 515       media_log_->CreateBooleanEvent( | 502       media_log_->CreateBooleanEvent( | 
| 516           MediaLogEvent::NETWORK_ACTIVITY_SET, | 503           MediaLogEvent::NETWORK_ACTIVITY_SET, | 
| 517           "is_downloading_data", is_downloading_data)); | 504           "is_downloading_data", is_downloading_data)); | 
| 518 } | 505 } | 
| 519 | 506 | 
| 520 void Pipeline::DisableAudioRenderer() { | 507 void Pipeline::DisableAudioRenderer() { | 
| 521   DCHECK(IsRunning()); | 508   DCHECK(IsRunning()); | 
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 966 | 953 | 
| 967     base::AutoLock auto_lock(lock_); | 954     base::AutoLock auto_lock(lock_); | 
| 968     // We use audio stream to update the clock. So if there is such a stream, | 955     // We use audio stream to update the clock. So if there is such a stream, | 
| 969     // we pause the clock until we receive a valid timestamp. | 956     // we pause the clock until we receive a valid timestamp. | 
| 970     waiting_for_clock_update_ = true; | 957     waiting_for_clock_update_ = true; | 
| 971     if (!has_audio_) { | 958     if (!has_audio_) { | 
| 972       clock_->SetMaxTime(clock_->Duration()); | 959       clock_->SetMaxTime(clock_->Duration()); | 
| 973       StartClockIfWaitingForTimeUpdate_Locked(); | 960       StartClockIfWaitingForTimeUpdate_Locked(); | 
| 974     } | 961     } | 
| 975 | 962 | 
| 976     // Start monitoring rate of downloading. |  | 
| 977     int bitrate = 0; |  | 
| 978     if (demuxer_) { |  | 
| 979       bitrate = demuxer_->GetBitrate(); |  | 
| 980       local_source_ = demuxer_->IsLocalSource(); |  | 
| 981       streaming_ = !demuxer_->IsSeekable(); |  | 
| 982     } |  | 
| 983     // Needs to be locked because most other calls to |download_rate_monitor_| |  | 
| 984     // occur on the renderer thread. |  | 
| 985     download_rate_monitor_.Start( |  | 
| 986         base::Bind(&Pipeline::OnCanPlayThrough, this), |  | 
| 987         bitrate, streaming_, local_source_); |  | 
| 988     download_rate_monitor_.SetBufferedBytes(buffered_bytes_, base::Time::Now()); |  | 
| 989 |  | 
| 990     if (IsPipelineStopPending()) { | 963     if (IsPipelineStopPending()) { | 
| 991       // We had a pending stop request need to be honored right now. | 964       // We had a pending stop request need to be honored right now. | 
| 992       TearDownPipeline(); | 965       TearDownPipeline(); | 
| 993     } | 966     } | 
| 994   } else { | 967   } else { | 
| 995     NOTREACHED() << "Unexpected state: " << state_; | 968     NOTREACHED() << "Unexpected state: " << state_; | 
| 996   } | 969   } | 
| 997 } | 970 } | 
| 998 | 971 | 
| 999 void Pipeline::TeardownStateTransitionTask() { | 972 void Pipeline::TeardownStateTransitionTask() { | 
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1326     return; | 1299     return; | 
| 1327   } | 1300   } | 
| 1328 | 1301 | 
| 1329   if (state_ != kStarted) | 1302   if (state_ != kStarted) | 
| 1330     return; | 1303     return; | 
| 1331 | 1304 | 
| 1332   if (audio_renderer_) | 1305   if (audio_renderer_) | 
| 1333     audio_renderer_->ResumeAfterUnderflow(true); | 1306     audio_renderer_->ResumeAfterUnderflow(true); | 
| 1334 } | 1307 } | 
| 1335 | 1308 | 
| 1336 void Pipeline::OnCanPlayThrough() { |  | 
| 1337   message_loop_->PostTask(FROM_HERE, base::Bind( |  | 
| 1338       &Pipeline::NotifyCanPlayThrough, this)); |  | 
| 1339 } |  | 
| 1340 |  | 
| 1341 void Pipeline::NotifyCanPlayThrough() { |  | 
| 1342   DCHECK(message_loop_->BelongsToCurrentThread()); |  | 
| 1343   NotifyNetworkEventTask(CAN_PLAY_THROUGH); |  | 
| 1344 } |  | 
| 1345 |  | 
| 1346 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 1309 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 
| 1347   lock_.AssertAcquired(); | 1310   lock_.AssertAcquired(); | 
| 1348   if (!waiting_for_clock_update_) | 1311   if (!waiting_for_clock_update_) | 
| 1349     return; | 1312     return; | 
| 1350 | 1313 | 
| 1351   waiting_for_clock_update_ = false; | 1314   waiting_for_clock_update_ = false; | 
| 1352   clock_->Play(); | 1315   clock_->Play(); | 
| 1353 } | 1316 } | 
| 1354 | 1317 | 
| 1355 }  // namespace media | 1318 }  // namespace media | 
| OLD | NEW | 
|---|