Index: media/filters/chunk_demuxer.cc |
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
index b1c238940d38405c4e079fb0d60c8cefbf3b41f0..e866da3de43c2b48105798225ab9ebd2b6a50cb5 100644 |
--- a/media/filters/chunk_demuxer.cc |
+++ b/media/filters/chunk_demuxer.cc |
@@ -176,6 +176,9 @@ class ChunkDemuxerStream : public DemuxerStream { |
// Returns true if buffers were successfully added. |
bool Append(const StreamParser::BufferQueue& buffers); |
+ // Returns the range of buffered data in this stream, capped at |duration|. |
+ Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const; |
+ |
// Signal to the stream that buffers handed in through subsequent calls to |
// Append() belong to a media segment that starts at |start_timestamp|. |
void OnNewMediaSegment(TimeDelta start_timestamp); |
@@ -199,7 +202,6 @@ class ChunkDemuxerStream : public DemuxerStream { |
virtual void EnableBitstreamConverter() OVERRIDE; |
virtual const AudioDecoderConfig& audio_decoder_config() OVERRIDE; |
virtual const VideoDecoderConfig& video_decoder_config() OVERRIDE; |
- virtual Ranges<TimeDelta> GetBufferedRanges() OVERRIDE; |
protected: |
virtual ~ChunkDemuxerStream(); |
@@ -318,9 +320,20 @@ bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) { |
return true; |
} |
-Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges() { |
+Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges( |
+ base::TimeDelta duration) const { |
base::AutoLock auto_lock(lock_); |
- return stream_->GetBufferedTime(); |
+ Ranges<TimeDelta> range = stream_->GetBufferedTime(); |
+ |
+ if (range.size() == 0u) |
+ return range; |
+ |
+ // Clamp the end of the stream's buffered ranges to fit within the duration. |
+ // This can be done by intersecting the stream's range with the valid time |
+ // range. |
+ Ranges<TimeDelta> valid_time_range; |
+ valid_time_range.Add(range.start(0), duration); |
+ return range.IntersectionWith(valid_time_range); |
} |
bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) { |
@@ -671,12 +684,12 @@ Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const { |
if (id == source_id_audio_ && id != source_id_video_) { |
// Only include ranges that have been buffered in |audio_| |
- return audio_ ? audio_->GetBufferedRanges() : Ranges<TimeDelta>(); |
+ return audio_ ? audio_->GetBufferedRanges(duration_) : Ranges<TimeDelta>(); |
} |
if (id != source_id_audio_ && id == source_id_video_) { |
// Only include ranges that have been buffered in |video_| |
- return video_ ? video_->GetBufferedRanges() : Ranges<TimeDelta>(); |
+ return video_ ? video_->GetBufferedRanges(duration_) : Ranges<TimeDelta>(); |
} |
return ComputeIntersection(); |
@@ -689,8 +702,8 @@ Ranges<TimeDelta> ChunkDemuxer::ComputeIntersection() const { |
return Ranges<TimeDelta>(); |
// Include ranges that have been buffered in both |audio_| and |video_|. |
- Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(); |
- Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(); |
+ Ranges<TimeDelta> audio_ranges = audio_->GetBufferedRanges(duration_); |
+ Ranges<TimeDelta> video_ranges = video_->GetBufferedRanges(duration_); |
Ranges<TimeDelta> result = audio_ranges.IntersectionWith(video_ranges); |
if (state_ == ENDED && result.size() > 0) { |
@@ -763,13 +776,7 @@ bool ChunkDemuxer::AppendData(const std::string& id, |
std::swap(cb, seek_cb_); |
} |
- if (audio_ && !video_) { |
- ranges = audio_->GetBufferedRanges(); |
- } else if (!audio_ && video_) { |
- ranges = video_->GetBufferedRanges(); |
- } else { |
- ranges = ComputeIntersection(); |
- } |
+ ranges = GetBufferedRanges(); |
} |
for (size_t i = 0; i < ranges.size(); ++i) |
@@ -825,10 +832,12 @@ bool ChunkDemuxer::EndOfStream(PipelineStatus status) { |
if (video_) |
video_->EndOfStream(); |
- if (status != PIPELINE_OK) |
+ if (status != PIPELINE_OK) { |
ReportError_Locked(status); |
- else |
+ } else { |
ChangeState_Locked(ENDED); |
+ DecreaseDurationIfNecessary(); |
+ } |
return true; |
} |
@@ -1121,7 +1130,7 @@ void ChunkDemuxer::IncreaseDurationIfNecessary( |
if (buffers.back()->GetTimestamp() <= duration_) |
return; |
- Ranges<TimeDelta> ranges = stream->GetBufferedRanges(); |
+ Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration()); |
DCHECK_GT(ranges.size(), 0u); |
base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); |
@@ -1129,4 +1138,22 @@ void ChunkDemuxer::IncreaseDurationIfNecessary( |
UpdateDuration(last_timestamp_buffered); |
} |
+void ChunkDemuxer::DecreaseDurationIfNecessary() { |
+ Ranges<TimeDelta> ranges = GetBufferedRanges(); |
+ if (ranges.size() == 0u) |
+ return; |
+ |
+ base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1); |
+ if (last_timestamp_buffered < duration_) |
+ UpdateDuration(last_timestamp_buffered); |
+} |
+ |
+Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { |
+ if (audio_ && !video_) |
+ return audio_->GetBufferedRanges(duration_); |
+ else if (!audio_ && video_) |
+ return video_->GetBufferedRanges(duration_); |
+ return ComputeIntersection(); |
+} |
+ |
} // namespace media |