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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 10539115: Calculate the buffered ranges in ChunkDemuxer::GetBufferedRanges() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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
Index: media/filters/chunk_demuxer.cc
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 1e1615465a4b53dc727f56b6d1b6ea49ea7fd0ee..f0fd62b3bbb1b477d54c6b1144713f640a36391e 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -133,6 +133,9 @@ class ChunkDemuxerStream : public DemuxerStream {
// Returns true if buffers were successfully added.
bool Append(const StreamParser::BufferQueue& buffers);
+ // Returns a list of the buffered time ranges.
+ SourceBufferStream::TimespanList GetBufferedTime() const;
+
// Called when mid-stream config updates occur.
// Returns true if the new config is accepted.
// Returns false if the new config should trigger an error.
@@ -246,6 +249,11 @@ bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {
return true;
}
+SourceBufferStream::TimespanList ChunkDemuxerStream::GetBufferedTime() const {
+ base::AutoLock auto_lock(lock_);
+ return stream_->GetBufferedTime();
+}
+
bool ChunkDemuxerStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
DCHECK(config.IsValidConfig());
DCHECK_EQ(type_, AUDIO);
@@ -580,12 +588,102 @@ bool ChunkDemuxer::GetBufferedRanges(const std::string& id,
Ranges* ranges_out) const {
DCHECK(!id.empty());
DCHECK_GT(stream_parser_map_.count(id), 0u);
+ DCHECK(id == source_id_audio_ || id == source_id_video_);
DCHECK(ranges_out);
base::AutoLock auto_lock(lock_);
+ bool success = false;
+
+ if (id == source_id_audio_ && id != source_id_video_) {
+ // Only include ranges that have been buffered in |audio_|
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 Move this to a helper method so we don't have dupl
annacc 2012/06/13 00:00:01 Done.
+ SourceBufferStream::TimespanList audio_ranges = audio_->GetBufferedTime();
+ for (SourceBufferStream::TimespanList::iterator itr = audio_ranges.begin();
+ itr != audio_ranges.end(); ++itr) {
+ ranges_out->push_back(*itr);
+ success = true;
+ }
+ return success;
+ }
- // TODO(annacc): Calculate buffered ranges (http://crbug.com/129852 ).
- return false;
+ if (id != source_id_audio_ && id == source_id_video_) {
+ // Only include ranges that have been buffered in |video_|
+ SourceBufferStream::TimespanList video_ranges = video_->GetBufferedTime();
+ for (SourceBufferStream::TimespanList::iterator itr = video_ranges.begin();
+ itr != video_ranges.end(); ++itr) {
+ ranges_out->push_back(*itr);
+ success = true;
+ }
+ return success;
+ }
+
+ // Include ranges that have been buffered in both |audio_| and |video_|.
+ SourceBufferStream::TimespanList audio_ranges = audio_->GetBufferedTime();
+ SourceBufferStream::TimespanList video_ranges = video_->GetBufferedTime();
+ SourceBufferStream::TimespanList::const_iterator video_ranges_itr =
+ video_ranges.begin();
+ SourceBufferStream::TimespanList::const_iterator audio_ranges_itr =
+ audio_ranges.begin();
+
+ while (audio_ranges_itr != audio_ranges.end() &&
+ video_ranges_itr != video_ranges.end()) {
+
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 Precompute the "last ranges" condition into a bool
annacc 2012/06/13 00:00:01 Done.
+ // Audio range start time is within the video range.
+ if ((*audio_ranges_itr).first >= (*video_ranges_itr).first &&
+ (*audio_ranges_itr).first <= (*video_ranges_itr).second) {
+ AddIntersectionRange(audio_ranges_itr, video_ranges_itr,
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 How about passing in *xxx_itr instead of the itera
annacc 2012/06/13 00:00:01 I think I've realized your suggestion here, but yo
+ audio_ranges.end(), video_ranges.end(),
+ ranges_out);
+ success = true;
+ continue;
+ }
+
+ // Video range start time is within the audio range.
+ if ((*video_ranges_itr).first >= (*audio_ranges_itr).first &&
+ (*video_ranges_itr).first <= (*audio_ranges_itr).second) {
+ AddIntersectionRange(video_ranges_itr, audio_ranges_itr,
+ video_ranges.end(), audio_ranges.end(),
+ ranges_out);
+ success = true;
+ continue;
+ }
+
+ // No overlap was found. Increment the smallest one and keep looking.
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: smallest -> earliest?
annacc 2012/06/13 00:00:01 Done.
+ if ((*audio_ranges_itr).first < (*video_ranges_itr).first)
+ audio_ranges_itr++;
+ else
+ video_ranges_itr++;
+ }
+
+ return success;
+}
+
+void ChunkDemuxer::AddIntersectionRange(
+ SourceBufferStream::TimespanList::const_iterator& itr_a,
+ SourceBufferStream::TimespanList::const_iterator& itr_b,
+ SourceBufferStream::TimespanList::const_iterator itr_a_end,
+ SourceBufferStream::TimespanList::const_iterator itr_b_end,
+ Ranges* ranges_out) const {
+ base::TimeDelta start = (*itr_a).first;
+
+ // If this is the last range and EndOfStream() was called (i.e. all data
+ // has been appended), choose the max end point of the ranges.
+ base::TimeDelta end;
+ if (state_ == ENDED &&
+ next(itr_a) == itr_a_end &&
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: Use (itr_a + 1) instead.
annacc 2012/06/13 00:00:01 Done.
+ next(itr_b) == itr_b_end) {
+ end = std::max((*itr_a).second, (*itr_b).second);
+ } else {
+ end = std::min((*itr_a).second, (*itr_b).second);
+ }
+
+ ranges_out->push_back(std::make_pair(start, end));
+
+ itr_a++;
+}
+
+SourceBufferStream::TimespanList::const_iterator ChunkDemuxer::next(
acolwell GONE FROM CHROMIUM 2012/06/12 22:48:13 nit: I'd prefer you use (itr + 1) instead of defin
annacc 2012/06/13 00:00:01 Done.
+ SourceBufferStream::TimespanList::const_iterator itr) const {
+ return ++itr;
}
bool ChunkDemuxer::AppendData(const std::string& id,

Powered by Google App Engine
This is Rietveld 408576698