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

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 10558011: Fix ChunkDemuxer so it properly outputs buffered ranges. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address more CR comments and added an end of stream test case. 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/filters/source_buffer_stream.h" 5 #include "media/filters/source_buffer_stream.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // filled with a valid buffer, false if there is not enough data to fulfill 79 // filled with a valid buffer, false if there is not enough data to fulfill
80 // the request. 80 // the request.
81 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); 81 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
82 bool HasNextBuffer() const; 82 bool HasNextBuffer() const;
83 83
84 // Returns the timestamp of the next buffer that will be returned from 84 // Returns the timestamp of the next buffer that will be returned from
85 // GetNextBuffer(). Returns kNoTimestamp() if Seek() has never been called or 85 // GetNextBuffer(). Returns kNoTimestamp() if Seek() has never been called or
86 // if this range does not have the next buffer yet. 86 // if this range does not have the next buffer yet.
87 base::TimeDelta GetNextTimestamp() const; 87 base::TimeDelta GetNextTimestamp() const;
88 88
89 // Returns the start timestamp of the range.
90 base::TimeDelta GetStartTimestamp() const;
91
89 // Returns the end timestamp of the buffered data. (Note that this is equal to 92 // Returns the end timestamp of the buffered data. (Note that this is equal to
90 // the last buffer's timestamp + its duration.) 93 // the last buffer's timestamp + its duration.)
91 base::TimeDelta GetEndTimestamp() const; 94 base::TimeDelta GetEndTimestamp() const;
92 95
93 // Returns the Timespan of buffered time in this range.
94 SourceBufferStream::Timespan GetBufferedTime() const;
95
96 // Returns whether a buffer with a starting timestamp of |timestamp| would 96 // Returns whether a buffer with a starting timestamp of |timestamp| would
97 // belong in this range. This includes a buffer that would be appended to 97 // belong in this range. This includes a buffer that would be appended to
98 // the end of the range. 98 // the end of the range.
99 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears 99 // Returns 0 if |timestamp| is in this range, -1 if |timestamp| appears
100 // before this range, or 1 if |timestamp| appears after this range. 100 // before this range, or 1 if |timestamp| appears after this range.
101 int BelongsToRange(base::TimeDelta timestamp) const; 101 int BelongsToRange(base::TimeDelta timestamp) const;
102 102
103 // Returns true if the range has enough data to seek to the specified 103 // Returns true if the range has enough data to seek to the specified
104 // |timestamp|, false otherwise. 104 // |timestamp|, false otherwise.
105 bool CanSeekTo(base::TimeDelta timestamp) const; 105 bool CanSeekTo(base::TimeDelta timestamp) const;
106 106
107 // Returns true if this range's buffered timespan completely overlaps the 107 // Returns true if this range's buffered timespan completely overlaps the
108 // buffered timespan of |range|. 108 // buffered timespan of |range|.
109 bool CompletelyOverlaps(const SourceBufferRange& range) const; 109 bool CompletelyOverlaps(const SourceBufferRange& range) const;
110 110
111 // Returns true if the end of this range contains buffers that overlaps with 111 // Returns true if the end of this range contains buffers that overlaps with
112 // the beginning of |range|. 112 // the beginning of |range|.
113 bool EndOverlaps(const SourceBufferRange& range) const; 113 bool EndOverlaps(const SourceBufferRange& range) const;
114 114
115 private: 115 private:
116 // Helper method to delete buffers in |buffers_| starting from 116 // Helper method to delete buffers in |buffers_| starting from
117 // |starting_point|, an iterator in |buffers_|. 117 // |starting_point|, an iterator in |buffers_|.
118 void DeleteAfter(const BufferQueue::iterator& starting_point, 118 void DeleteAfter(const BufferQueue::iterator& starting_point,
119 BufferQueue* deleted_buffers, 119 BufferQueue* deleted_buffers,
120 BufferQueue::iterator* next_buffer); 120 BufferQueue::iterator* next_buffer);
121 121
122 // Returns the start timestamp of the range.
123 base::TimeDelta GetStartTimestamp() const;
124
125 // An ordered list of buffers in this range. 122 // An ordered list of buffers in this range.
126 BufferQueue buffers_; 123 BufferQueue buffers_;
127 124
128 // Maps keyframe timestamps to its index position in |buffers_|. 125 // Maps keyframe timestamps to its index position in |buffers_|.
129 typedef std::map<base::TimeDelta, size_t> KeyframeMap; 126 typedef std::map<base::TimeDelta, size_t> KeyframeMap;
130 KeyframeMap keyframe_map_; 127 KeyframeMap keyframe_map_;
131 128
132 // Index into |buffers_| for the next buffer to be returned by 129 // Index into |buffers_| for the next buffer to be returned by
133 // GetBufferedTime(), set to -1 before Seek(). 130 // GetNextBuffer(), set to -1 before Seek().
134 int next_buffer_index_; 131 int next_buffer_index_;
135 132
136 // True if the range needs to wait for the next keyframe to be appended before 133 // True if the range needs to wait for the next keyframe to be appended before
137 // returning buffers from GetNextBuffer(). 134 // returning buffers from GetNextBuffer().
138 bool waiting_for_keyframe_; 135 bool waiting_for_keyframe_;
139 136
140 // If |waiting_for_keyframe_| is true, this range will wait for the next 137 // If |waiting_for_keyframe_| is true, this range will wait for the next
141 // keyframe with timestamp >= |next_keyframe_timestamp_|. 138 // keyframe with timestamp >= |next_keyframe_timestamp_|.
142 base::TimeDelta next_keyframe_timestamp_; 139 base::TimeDelta next_keyframe_timestamp_;
143 140
(...skipping 12 matching lines...) Expand all
156 153
157 } // namespace media 154 } // namespace media
158 155
159 // Helper method that returns true if |ranges| is sorted in increasing order, 156 // Helper method that returns true if |ranges| is sorted in increasing order,
160 // false otherwise. 157 // false otherwise.
161 static bool IsRangeListSorted( 158 static bool IsRangeListSorted(
162 const std::list<media::SourceBufferRange*>& ranges) { 159 const std::list<media::SourceBufferRange*>& ranges) {
163 base::TimeDelta prev = media::kNoTimestamp(); 160 base::TimeDelta prev = media::kNoTimestamp();
164 for (std::list<media::SourceBufferRange*>::const_iterator itr = 161 for (std::list<media::SourceBufferRange*>::const_iterator itr =
165 ranges.begin(); itr != ranges.end(); itr++) { 162 ranges.begin(); itr != ranges.end(); itr++) {
166 media::SourceBufferStream::Timespan buffered = (*itr)->GetBufferedTime(); 163 if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp())
167 if (prev != media::kNoTimestamp() && prev >= buffered.first)
168 return false; 164 return false;
169 prev = buffered.second; 165 prev = (*itr)->GetEndTimestamp();
170 } 166 }
171 return true; 167 return true;
172 } 168 }
173 169
174 // Comparison function for two Buffers based on timestamp. 170 // Comparison function for two Buffers based on timestamp.
175 static bool BufferComparator( 171 static bool BufferComparator(
176 const scoped_refptr<media::StreamParserBuffer>& first, 172 const scoped_refptr<media::StreamParserBuffer>& first,
177 const scoped_refptr<media::StreamParserBuffer>& second) { 173 const scoped_refptr<media::StreamParserBuffer>& second) {
178 return first->GetTimestamp() < second->GetTimestamp(); 174 return first->GetTimestamp() < second->GetTimestamp();
179 } 175 }
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 492
497 if (end_of_stream_ && (!selected_range_ || 493 if (end_of_stream_ && (!selected_range_ ||
498 !selected_range_->HasNextBuffer())) { 494 !selected_range_->HasNextBuffer())) {
499 *out_buffer = StreamParserBuffer::CreateEOSBuffer(); 495 *out_buffer = StreamParserBuffer::CreateEOSBuffer();
500 return true; 496 return true;
501 } 497 }
502 498
503 return selected_range_ && selected_range_->GetNextBuffer(out_buffer); 499 return selected_range_ && selected_range_->GetNextBuffer(out_buffer);
504 } 500 }
505 501
506 SourceBufferStream::TimespanList SourceBufferStream::GetBufferedTime() const { 502 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
507 TimespanList timespans; 503 Ranges<base::TimeDelta> ranges;
508 for (RangeList::const_iterator itr = ranges_.begin(); 504 for (RangeList::const_iterator itr = ranges_.begin();
509 itr != ranges_.end(); itr++) { 505 itr != ranges_.end(); itr++) {
510 timespans.push_back((*itr)->GetBufferedTime()); 506 ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetEndTimestamp());
511 } 507 }
512 return timespans; 508 return ranges;
513 } 509 }
514 510
515 void SourceBufferStream::EndOfStream() { 511 void SourceBufferStream::EndOfStream() {
516 DCHECK(CanEndOfStream()); 512 DCHECK(CanEndOfStream());
517 end_of_stream_ = true; 513 end_of_stream_ = true;
518 } 514 }
519 515
520 bool SourceBufferStream::CanEndOfStream() const { 516 bool SourceBufferStream::CanEndOfStream() const {
521 return ranges_.empty() || selected_range_ == ranges_.back(); 517 return ranges_.empty() || selected_range_ == ranges_.back();
522 } 518 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 DCHECK(!buffers_.empty()); 692 DCHECK(!buffers_.empty());
697 693
698 if (next_buffer_index_ >= static_cast<int>(buffers_.size()) || 694 if (next_buffer_index_ >= static_cast<int>(buffers_.size()) ||
699 next_buffer_index_ < 0 || waiting_for_keyframe_) { 695 next_buffer_index_ < 0 || waiting_for_keyframe_) {
700 return kNoTimestamp(); 696 return kNoTimestamp();
701 } 697 }
702 698
703 return buffers_.at(next_buffer_index_)->GetTimestamp(); 699 return buffers_.at(next_buffer_index_)->GetTimestamp();
704 } 700 }
705 701
706 SourceBufferStream::Timespan
707 SourceBufferRange::GetBufferedTime() const {
708 return std::make_pair(GetStartTimestamp(), GetEndTimestamp());
709 }
710
711 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range, 702 void SourceBufferRange::AppendToEnd(const SourceBufferRange& range,
712 bool transfer_current_position) { 703 bool transfer_current_position) {
713 DCHECK(CanAppendToEnd(range)); 704 DCHECK(CanAppendToEnd(range));
714 DCHECK(!buffers_.empty()); 705 DCHECK(!buffers_.empty());
715 706
716 if (transfer_current_position) 707 if (transfer_current_position)
717 next_buffer_index_ = range.next_buffer_index_ + buffers_.size(); 708 next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
718 709
719 AppendToEnd(range.buffers_); 710 AppendToEnd(range.buffers_);
720 } 711 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 start_timestamp = buffers_.front()->GetTimestamp(); 757 start_timestamp = buffers_.front()->GetTimestamp();
767 return start_timestamp; 758 return start_timestamp;
768 } 759 }
769 760
770 base::TimeDelta SourceBufferRange::GetEndTimestamp() const { 761 base::TimeDelta SourceBufferRange::GetEndTimestamp() const {
771 DCHECK(!buffers_.empty()); 762 DCHECK(!buffers_.empty());
772 return buffers_.back()->GetEndTimestamp(); 763 return buffers_.back()->GetEndTimestamp();
773 } 764 }
774 765
775 } // namespace media 766 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/source_buffer_stream.h ('k') | media/filters/source_buffer_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698