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 |