Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(807)

Unified Diff: media/base/pipeline.cc

Issue 10451049: Track buffered byte ranges correctly in media::Pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/pipeline.cc
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 607cf8c932921d3492435139dda16275d31dc9ed..4b4fec0ac4941068bd308e53d28ed8f5fef61314 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -24,6 +24,8 @@
#include "media/base/video_decoder.h"
#include "media/base/video_renderer.h"
+using base::TimeDelta;
+
namespace media {
PipelineStatusNotification::PipelineStatusNotification()
@@ -73,7 +75,6 @@ Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log)
clock_(new Clock(&base::Time::Now)),
waiting_for_clock_update_(false),
state_(kCreated),
- current_bytes_(0),
creation_time_(base::Time::Now()) {
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
ResetState();
@@ -114,8 +115,7 @@ void Pipeline::Stop(const base::Closure& stop_cb) {
&Pipeline::StopTask, this, stop_cb));
}
-void Pipeline::Seek(base::TimeDelta time,
- const PipelineStatusCB& seek_cb) {
+void Pipeline::Seek(TimeDelta time, const PipelineStatusCB& seek_cb) {
base::AutoLock auto_lock(lock_);
CHECK(running_) << "Media pipeline isn't running";
@@ -190,29 +190,43 @@ void Pipeline::SetVolume(float volume) {
}
}
-base::TimeDelta Pipeline::GetCurrentTime() const {
+TimeDelta Pipeline::GetCurrentTime() const {
base::AutoLock auto_lock(lock_);
return GetCurrentTime_Locked();
}
-base::TimeDelta Pipeline::GetCurrentTime_Locked() const {
+TimeDelta Pipeline::GetCurrentTime_Locked() const {
lock_.AssertAcquired();
return clock_->Elapsed();
}
-Ranges<base::TimeDelta> Pipeline::GetBufferedTimeRanges() {
+Ranges<TimeDelta> Pipeline::GetBufferedTimeRanges() {
base::AutoLock auto_lock(lock_);
- return buffered_time_ranges_;
+ Ranges<TimeDelta> time_ranges;
+ if (clock_->Duration() == TimeDelta() || total_bytes_ == 0)
+ return time_ranges;
+ for (size_t i = 0; i < buffered_byte_ranges_.size(); ++i) {
+ TimeDelta start = TimeForByteOffset_Locked(buffered_byte_ranges_.start(i));
+ TimeDelta end = TimeForByteOffset_Locked(buffered_byte_ranges_.end(i));
+ // Cap approximated buffered time at the length of the video.
+ end = std::min(end, clock_->Duration());
+ time_ranges.Add(start, end);
+ }
+
+ return time_ranges;
}
-base::TimeDelta Pipeline::GetMediaDuration() const {
+TimeDelta Pipeline::GetMediaDuration() const {
base::AutoLock auto_lock(lock_);
return clock_->Duration();
}
int64 Pipeline::GetBufferedBytes() const {
base::AutoLock auto_lock(lock_);
- return buffered_bytes_;
+ int64 ret = 0;
+ for (size_t i = 0; i < buffered_byte_ranges_.size(); ++i)
+ ret += buffered_byte_ranges_.end(i) - buffered_byte_ranges_.start(i);
+ return ret;
}
int64 Pipeline::GetTotalBytes() const {
@@ -235,31 +249,16 @@ void Pipeline::SetClockForTesting(Clock* clock) {
clock_.reset(clock);
}
-void Pipeline::SetCurrentReadPosition(int64 offset) {
- base::AutoLock auto_lock(lock_);
-
- // The current read position should never be ahead of the buffered byte
- // position but threading issues between BufferedDataSource::DoneRead_Locked()
- // and BufferedDataSource::NetworkEventCallback() can cause them to be
- // temporarily out of sync. The easiest fix for this is to cap both
- // buffered_bytes_ and current_bytes_ to always be legal values in
- // SetCurrentReadPosition() and in SetBufferedBytes().
- if (offset > buffered_bytes_)
- buffered_bytes_ = offset;
- current_bytes_ = offset;
-}
-
void Pipeline::ResetState() {
base::AutoLock auto_lock(lock_);
- const base::TimeDelta kZero;
+ const TimeDelta kZero;
running_ = false;
stop_pending_ = false;
seek_pending_ = false;
tearing_down_ = false;
error_caused_teardown_ = false;
playback_rate_change_pending_ = false;
- buffered_bytes_ = 0;
- buffered_time_ranges_.clear();
+ buffered_byte_ranges_.clear();
total_bytes_ = 0;
natural_size_.SetSize(0, 0);
volume_ = 1.0f;
@@ -378,18 +377,17 @@ void Pipeline::SetError(PipelineStatus error) {
media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error));
}
-base::TimeDelta Pipeline::GetTime() const {
+TimeDelta Pipeline::GetTime() const {
DCHECK(IsRunning());
return GetCurrentTime();
}
-base::TimeDelta Pipeline::GetDuration() const {
+TimeDelta Pipeline::GetDuration() const {
DCHECK(IsRunning());
return GetMediaDuration();
}
-void Pipeline::OnAudioTimeUpdate(base::TimeDelta time,
- base::TimeDelta max_time) {
+void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) {
DCHECK(time <= max_time);
DCHECK(IsRunning());
base::AutoLock auto_lock(lock_);
@@ -403,7 +401,7 @@ void Pipeline::OnAudioTimeUpdate(base::TimeDelta time,
StartClockIfWaitingForTimeUpdate_Locked();
}
-void Pipeline::OnVideoTimeUpdate(base::TimeDelta max_time) {
+void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) {
DCHECK(IsRunning());
base::AutoLock auto_lock(lock_);
@@ -414,7 +412,7 @@ void Pipeline::OnVideoTimeUpdate(base::TimeDelta max_time) {
clock_->SetMaxTime(max_time);
}
-void Pipeline::SetDuration(base::TimeDelta duration) {
+void Pipeline::SetDuration(TimeDelta duration) {
DCHECK(IsRunning());
media_log_->AddEvent(
media_log_->CreateTimeEvent(
@@ -423,7 +421,6 @@ void Pipeline::SetDuration(base::TimeDelta duration) {
base::AutoLock auto_lock(lock_);
clock_->SetDuration(duration);
- UpdateBufferedTimeRanges_Locked();
}
void Pipeline::SetTotalBytes(int64 total_bytes) {
@@ -441,29 +438,23 @@ void Pipeline::SetTotalBytes(int64 total_bytes) {
total_bytes_ = total_bytes;
}
-void Pipeline::SetBufferedBytes(int64 buffered_bytes) {
+TimeDelta Pipeline::TimeForByteOffset_Locked(int64 byte_offset) const {
+ lock_.AssertAcquired();
+ TimeDelta time_offset = byte_offset * clock_->Duration() / total_bytes_;
+ // Since the byte->time calculation is approximate, fudge the beginning &
+ // ending areas to look better.
+ TimeDelta epsilon = clock_->Duration() / 100;
+ if (time_offset < epsilon)
+ return TimeDelta();
+ if (time_offset + epsilon > clock_->Duration())
+ return clock_->Duration();
+ return time_offset;
+}
+
+void Pipeline::AddBufferedByteRange(int64 start, int64 end) {
DCHECK(IsRunning());
base::AutoLock auto_lock(lock_);
- // See comments in SetCurrentReadPosition() about capping.
- if (buffered_bytes < current_bytes_)
- current_bytes_ = buffered_bytes;
- buffered_bytes_ = buffered_bytes;
- UpdateBufferedTimeRanges_Locked();
-}
-
-void Pipeline::UpdateBufferedTimeRanges_Locked() {
- lock_.AssertAcquired();
- if (total_bytes_ == 0)
- return;
- base::TimeDelta buffered_time =
- clock_->Duration() * buffered_bytes_ / total_bytes_;
- // Cap approximated buffered time at the length of the video.
- buffered_time = std::min(buffered_time, clock_->Duration());
- // Make sure buffered_time is at least the current time and at least the
- // current seek target.
- buffered_time = std::max(buffered_time, GetCurrentTime_Locked());
- buffered_time = std::max(buffered_time, seek_timestamp_);
- buffered_time_ranges_.Add(seek_timestamp_, buffered_time);
+ buffered_byte_ranges_.Add(start, end);
}
void Pipeline::SetNaturalVideoSize(const gfx::Size& size) {
@@ -782,8 +773,7 @@ void Pipeline::VolumeChangedTask(float volume) {
audio_renderer_->SetVolume(volume);
}
-void Pipeline::SeekTask(base::TimeDelta time,
- const PipelineStatusCB& seek_cb) {
+void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(!IsPipelineStopPending());
@@ -1260,7 +1250,7 @@ void Pipeline::OnDemuxerStopDone(const base::Closure& callback) {
callback.Run();
}
-void Pipeline::DoSeek(base::TimeDelta seek_timestamp) {
+void Pipeline::DoSeek(TimeDelta seek_timestamp) {
// TODO(acolwell): We might be able to convert this if (demuxer_) into a
// DCHECK(). Further investigation is needed to make sure this won't introduce
// a bug.
@@ -1273,7 +1263,7 @@ void Pipeline::DoSeek(base::TimeDelta seek_timestamp) {
OnDemuxerSeekDone(seek_timestamp, PIPELINE_OK);
}
-void Pipeline::OnDemuxerSeekDone(base::TimeDelta seek_timestamp,
+void Pipeline::OnDemuxerSeekDone(TimeDelta seek_timestamp,
PipelineStatus status) {
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(FROM_HERE, base::Bind(
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698