| 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 namespace media { | 33 namespace media { |
| 34 | 34 |
| 35 Pipeline::Pipeline( | 35 Pipeline::Pipeline( |
| 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 37 MediaLog* media_log) | 37 MediaLog* media_log) |
| 38 : task_runner_(task_runner), | 38 : task_runner_(task_runner), |
| 39 media_log_(media_log), | 39 media_log_(media_log), |
| 40 running_(false), | 40 running_(false), |
| 41 did_loading_progress_(false), | 41 did_loading_progress_(false), |
| 42 total_bytes_(0), | |
| 43 volume_(1.0f), | 42 volume_(1.0f), |
| 44 playback_rate_(0.0f), | 43 playback_rate_(0.0f), |
| 45 clock_(new Clock(&default_tick_clock_)), | 44 clock_(new Clock(&default_tick_clock_)), |
| 46 waiting_for_clock_update_(false), | 45 waiting_for_clock_update_(false), |
| 47 status_(PIPELINE_OK), | 46 status_(PIPELINE_OK), |
| 48 state_(kCreated), | 47 state_(kCreated), |
| 49 audio_ended_(false), | 48 audio_ended_(false), |
| 50 video_ended_(false), | 49 video_ended_(false), |
| 51 text_ended_(false), | 50 text_ended_(false), |
| 52 audio_disabled_(false), | 51 audio_disabled_(false), |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 } | 153 } |
| 155 } | 154 } |
| 156 | 155 |
| 157 TimeDelta Pipeline::GetMediaTime() const { | 156 TimeDelta Pipeline::GetMediaTime() const { |
| 158 base::AutoLock auto_lock(lock_); | 157 base::AutoLock auto_lock(lock_); |
| 159 return clock_->Elapsed(); | 158 return clock_->Elapsed(); |
| 160 } | 159 } |
| 161 | 160 |
| 162 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { | 161 Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() { |
| 163 base::AutoLock auto_lock(lock_); | 162 base::AutoLock auto_lock(lock_); |
| 164 Ranges<TimeDelta> time_ranges; | 163 return buffered_time_ranges_; |
| 165 for (size_t i = 0; i < buffered_time_ranges_.size(); ++i) { | |
| 166 time_ranges.Add(buffered_time_ranges_.start(i), | |
| 167 buffered_time_ranges_.end(i)); | |
| 168 } | |
| 169 if (clock_->Duration() == TimeDelta() || total_bytes_ == 0) | |
| 170 return time_ranges; | |
| 171 for (size_t i = 0; i < buffered_byte_ranges_.size(); ++i) { | |
| 172 TimeDelta start = TimeForByteOffset_Locked(buffered_byte_ranges_.start(i)); | |
| 173 TimeDelta end = TimeForByteOffset_Locked(buffered_byte_ranges_.end(i)); | |
| 174 // Cap approximated buffered time at the length of the video. | |
| 175 end = std::min(end, clock_->Duration()); | |
| 176 time_ranges.Add(start, end); | |
| 177 } | |
| 178 | |
| 179 return time_ranges; | |
| 180 } | 164 } |
| 181 | 165 |
| 182 TimeDelta Pipeline::GetMediaDuration() const { | 166 TimeDelta Pipeline::GetMediaDuration() const { |
| 183 base::AutoLock auto_lock(lock_); | 167 base::AutoLock auto_lock(lock_); |
| 184 return clock_->Duration(); | 168 return clock_->Duration(); |
| 185 } | 169 } |
| 186 | 170 |
| 187 int64 Pipeline::GetTotalBytes() const { | |
| 188 base::AutoLock auto_lock(lock_); | |
| 189 return total_bytes_; | |
| 190 } | |
| 191 | |
| 192 bool Pipeline::DidLoadingProgress() const { | 171 bool Pipeline::DidLoadingProgress() const { |
| 193 base::AutoLock auto_lock(lock_); | 172 base::AutoLock auto_lock(lock_); |
| 194 bool ret = did_loading_progress_; | 173 bool ret = did_loading_progress_; |
| 195 did_loading_progress_ = false; | 174 did_loading_progress_ = false; |
| 196 return ret; | 175 return ret; |
| 197 } | 176 } |
| 198 | 177 |
| 199 PipelineStatistics Pipeline::GetStatistics() const { | 178 PipelineStatistics Pipeline::GetStatistics() const { |
| 200 base::AutoLock auto_lock(lock_); | 179 base::AutoLock auto_lock(lock_); |
| 201 return statistics_; | 180 return statistics_; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 media_log_->CreateTimeEvent( | 345 media_log_->CreateTimeEvent( |
| 367 MediaLogEvent::DURATION_SET, "duration", duration)); | 346 MediaLogEvent::DURATION_SET, "duration", duration)); |
| 368 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); | 347 UMA_HISTOGRAM_LONG_TIMES("Media.Duration", duration); |
| 369 | 348 |
| 370 base::AutoLock auto_lock(lock_); | 349 base::AutoLock auto_lock(lock_); |
| 371 clock_->SetDuration(duration); | 350 clock_->SetDuration(duration); |
| 372 if (!duration_change_cb_.is_null()) | 351 if (!duration_change_cb_.is_null()) |
| 373 duration_change_cb_.Run(); | 352 duration_change_cb_.Run(); |
| 374 } | 353 } |
| 375 | 354 |
| 376 void Pipeline::SetTotalBytes(int64 total_bytes) { | |
| 377 media_log_->AddEvent( | |
| 378 media_log_->CreateStringEvent( | |
| 379 MediaLogEvent::TOTAL_BYTES_SET, "total_bytes", | |
| 380 base::Int64ToString(total_bytes))); | |
| 381 int64 total_mbytes = total_bytes >> 20; | |
| 382 if (total_mbytes > kint32max) | |
| 383 total_mbytes = kint32max; | |
| 384 UMA_HISTOGRAM_CUSTOM_COUNTS( | |
| 385 "Media.TotalMBytes", static_cast<int32>(total_mbytes), 1, kint32max, 50); | |
| 386 | |
| 387 base::AutoLock auto_lock(lock_); | |
| 388 total_bytes_ = total_bytes; | |
| 389 } | |
| 390 | |
| 391 TimeDelta Pipeline::TimeForByteOffset_Locked(int64 byte_offset) const { | |
| 392 lock_.AssertAcquired(); | |
| 393 // Use floating point to avoid potential overflow when using 64 bit integers. | |
| 394 double time_offset_in_ms = clock_->Duration().InMilliseconds() * | |
| 395 (static_cast<double>(byte_offset) / total_bytes_); | |
| 396 TimeDelta time_offset(TimeDelta::FromMilliseconds( | |
| 397 static_cast<int64>(time_offset_in_ms))); | |
| 398 // Since the byte->time calculation is approximate, fudge the beginning & | |
| 399 // ending areas to look better. | |
| 400 TimeDelta epsilon = clock_->Duration() / 100; | |
| 401 if (time_offset < epsilon) | |
| 402 return TimeDelta(); | |
| 403 if (time_offset + epsilon > clock_->Duration()) | |
| 404 return clock_->Duration(); | |
| 405 return time_offset; | |
| 406 } | |
| 407 | |
| 408 void Pipeline::OnStateTransition(PipelineStatus status) { | 355 void Pipeline::OnStateTransition(PipelineStatus status) { |
| 409 // Force post to process state transitions after current execution frame. | 356 // Force post to process state transitions after current execution frame. |
| 410 task_runner_->PostTask(FROM_HERE, base::Bind( | 357 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 411 &Pipeline::StateTransitionTask, base::Unretained(this), status)); | 358 &Pipeline::StateTransitionTask, base::Unretained(this), status)); |
| 412 } | 359 } |
| 413 | 360 |
| 414 void Pipeline::StateTransitionTask(PipelineStatus status) { | 361 void Pipeline::StateTransitionTask(PipelineStatus status) { |
| 415 DCHECK(task_runner_->BelongsToCurrentThread()); | 362 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 416 | 363 |
| 417 // No-op any state transitions if we're stopping. | 364 // No-op any state transitions if we're stopping. |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 // NOTE: pipeline may be deleted at this point in time as a result of | 623 // NOTE: pipeline may be deleted at this point in time as a result of |
| 677 // executing |stop_cb_|. | 624 // executing |stop_cb_|. |
| 678 return; | 625 return; |
| 679 } | 626 } |
| 680 if (!error_cb_.is_null()) { | 627 if (!error_cb_.is_null()) { |
| 681 DCHECK_NE(status_, PIPELINE_OK); | 628 DCHECK_NE(status_, PIPELINE_OK); |
| 682 base::ResetAndReturn(&error_cb_).Run(status_); | 629 base::ResetAndReturn(&error_cb_).Run(status_); |
| 683 } | 630 } |
| 684 } | 631 } |
| 685 | 632 |
| 686 void Pipeline::AddBufferedByteRange(int64 start, int64 end) { | |
| 687 base::AutoLock auto_lock(lock_); | |
| 688 buffered_byte_ranges_.Add(start, end); | |
| 689 did_loading_progress_ = true; | |
| 690 } | |
| 691 | |
| 692 void Pipeline::AddBufferedTimeRange(base::TimeDelta start, | 633 void Pipeline::AddBufferedTimeRange(base::TimeDelta start, |
| 693 base::TimeDelta end) { | 634 base::TimeDelta end) { |
| 694 DCHECK(IsRunning()); | 635 DCHECK(IsRunning()); |
| 695 base::AutoLock auto_lock(lock_); | 636 base::AutoLock auto_lock(lock_); |
| 696 buffered_time_ranges_.Add(start, end); | 637 buffered_time_ranges_.Add(start, end); |
| 697 did_loading_progress_ = true; | 638 did_loading_progress_ = true; |
| 698 } | 639 } |
| 699 | 640 |
| 700 void Pipeline::OnAudioRendererEnded() { | 641 void Pipeline::OnAudioRendererEnded() { |
| 701 // Force post to process ended tasks after current execution frame. | 642 // Force post to process ended tasks after current execution frame. |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { | 927 void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { |
| 987 lock_.AssertAcquired(); | 928 lock_.AssertAcquired(); |
| 988 if (!waiting_for_clock_update_) | 929 if (!waiting_for_clock_update_) |
| 989 return; | 930 return; |
| 990 | 931 |
| 991 waiting_for_clock_update_ = false; | 932 waiting_for_clock_update_ = false; |
| 992 clock_->Play(); | 933 clock_->Play(); |
| 993 } | 934 } |
| 994 | 935 |
| 995 } // namespace media | 936 } // namespace media |
| OLD | NEW |