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_->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_->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 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
967 | 954 |
968 base::AutoLock auto_lock(lock_); | 955 base::AutoLock auto_lock(lock_); |
969 // We use audio stream to update the clock. So if there is such a stream, | 956 // We use audio stream to update the clock. So if there is such a stream, |
970 // we pause the clock until we receive a valid timestamp. | 957 // we pause the clock until we receive a valid timestamp. |
971 waiting_for_clock_update_ = true; | 958 waiting_for_clock_update_ = true; |
972 if (!has_audio_) { | 959 if (!has_audio_) { |
973 clock_->SetMaxTime(clock_->Duration()); | 960 clock_->SetMaxTime(clock_->Duration()); |
974 StartClockIfWaitingForTimeUpdate_Locked(); | 961 StartClockIfWaitingForTimeUpdate_Locked(); |
975 } | 962 } |
976 | 963 |
977 // Start monitoring rate of downloading. | |
978 int bitrate = 0; | |
979 if (demuxer_) { | |
980 bitrate = demuxer_->GetBitrate(); | |
981 local_source_ = demuxer_->IsLocalSource(); | |
982 streaming_ = !demuxer_->IsSeekable(); | |
983 } | |
984 // Needs to be locked because most other calls to |download_rate_monitor_| | |
985 // occur on the renderer thread. | |
986 download_rate_monitor_.Start( | |
987 base::Bind(&Pipeline::OnCanPlayThrough, this), | |
988 bitrate, streaming_, local_source_); | |
989 download_rate_monitor_.SetBufferedBytes(buffered_bytes_, base::Time::Now()); | |
990 | |
991 if (IsPipelineStopPending()) { | 964 if (IsPipelineStopPending()) { |
992 // We had a pending stop request need to be honored right now. | 965 // We had a pending stop request need to be honored right now. |
993 TearDownPipeline(); | 966 TearDownPipeline(); |
994 } | 967 } |
995 } else { | 968 } else { |
996 NOTREACHED() << "Unexpected state: " << state_; | 969 NOTREACHED() << "Unexpected state: " << state_; |
997 } | 970 } |
998 } | 971 } |
999 | 972 |
1000 void Pipeline::TeardownStateTransitionTask() { | 973 void Pipeline::TeardownStateTransitionTask() { |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 return; | 1300 return; |
1328 } | 1301 } |
1329 | 1302 |
1330 if (state_ != kStarted) | 1303 if (state_ != kStarted) |
1331 return; | 1304 return; |
1332 | 1305 |
1333 if (audio_renderer_) | 1306 if (audio_renderer_) |
1334 audio_renderer_->ResumeAfterUnderflow(true); | 1307 audio_renderer_->ResumeAfterUnderflow(true); |
1335 } | 1308 } |
1336 | 1309 |
1337 void Pipeline::OnCanPlayThrough() { | |
1338 message_loop_->PostTask(FROM_HERE, base::Bind( | |
1339 &Pipeline::NotifyCanPlayThrough, this)); | |
1340 } | |
1341 | |
1342 void Pipeline::NotifyCanPlayThrough() { | |
1343 DCHECK(message_loop_->BelongsToCurrentThread()); | |
1344 NotifyNetworkEventTask(CAN_PLAY_THROUGH); | |
1345 } | |
1346 | |
1347 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 1310 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
1348 lock_.AssertAcquired(); | 1311 lock_.AssertAcquired(); |
1349 if (!waiting_for_clock_update_) | 1312 if (!waiting_for_clock_update_) |
1350 return; | 1313 return; |
1351 | 1314 |
1352 waiting_for_clock_update_ = false; | 1315 waiting_for_clock_update_ = false; |
1353 clock_->Play(); | 1316 clock_->Play(); |
1354 } | 1317 } |
1355 | 1318 |
1356 } // namespace media | 1319 } // namespace media |
OLD | NEW |