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 #ifndef MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ | 5 #ifndef MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ |
6 #define MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ | 6 #define MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <list> | 9 #include <list> |
10 #include <utility> | 10 #include <utility> |
(...skipping 10 matching lines...) Expand all Loading... | |
21 class SourceBufferRange; | 21 class SourceBufferRange; |
22 | 22 |
23 // SourceBufferStream is a data structure that stores media Buffers in ranges. | 23 // SourceBufferStream is a data structure that stores media Buffers in ranges. |
24 // Buffers can be appended out of presentation order. Buffers are retrieved by | 24 // Buffers can be appended out of presentation order. Buffers are retrieved by |
25 // seeking to the desired start point and calling GetNextBuffer(). Buffers are | 25 // seeking to the desired start point and calling GetNextBuffer(). Buffers are |
26 // returned in sequential presentation order. | 26 // returned in sequential presentation order. |
27 class MEDIA_EXPORT SourceBufferStream { | 27 class MEDIA_EXPORT SourceBufferStream { |
28 public: | 28 public: |
29 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; | 29 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
30 | 30 |
31 SourceBufferStream(); | |
32 explicit SourceBufferStream(const AudioDecoderConfig& audio_config); | 31 explicit SourceBufferStream(const AudioDecoderConfig& audio_config); |
33 explicit SourceBufferStream(const VideoDecoderConfig& video_config); | 32 explicit SourceBufferStream(const VideoDecoderConfig& video_config); |
34 | 33 |
35 ~SourceBufferStream(); | 34 ~SourceBufferStream(); |
36 | 35 |
36 // Signals that the next buffers appended are part of a new media segment | |
37 // starting at |media_segment_start_time|. | |
38 void OnNewMediaSegment(base::TimeDelta media_segment_start_time); | |
39 | |
37 // Add the |buffers| to the SourceBufferStream. Buffers within the queue are | 40 // Add the |buffers| to the SourceBufferStream. Buffers within the queue are |
38 // expected to be in order, but multiple calls to Append() may add buffers out | 41 // expected to be in order, but multiple calls to Append() may add buffers out |
39 // of order or overlapping. Assumes all buffers within |buffers| are in | 42 // of order or overlapping. Assumes all buffers within |buffers| are in |
40 // presentation order and are non-overlapping. | 43 // presentation order and are non-overlapping. |
41 // |media_segment_start_time| refers to the starting timestamp for the media | |
42 // segment to which these buffers belong. | |
43 // Returns true if Append() was successful, false if |buffers| are not added. | 44 // Returns true if Append() was successful, false if |buffers| are not added. |
44 // TODO(vrk): Implement garbage collection. (crbug.com/125070) | 45 // TODO(vrk): Implement garbage collection. (crbug.com/125070) |
45 bool Append(const BufferQueue& buffers, | 46 bool Append(const BufferQueue& buffers); |
46 base::TimeDelta media_segment_start_time); | |
47 | 47 |
48 // Changes the SourceBufferStream's state so that it will start returning | 48 // Changes the SourceBufferStream's state so that it will start returning |
49 // buffers starting from the closest keyframe before |timestamp|. | 49 // buffers starting from the closest keyframe before |timestamp|. |
50 void Seek(base::TimeDelta timestamp); | 50 void Seek(base::TimeDelta timestamp); |
51 | 51 |
52 // Returns true if the SourceBufferStream has seeked to a time without | 52 // Returns true if the SourceBufferStream has seeked to a time without |
53 // buffered data and is waiting for more data to be appended. | 53 // buffered data and is waiting for more data to be appended. |
54 bool IsSeekPending() const; | 54 bool IsSeekPending() const; |
55 | 55 |
56 // Fills |out_buffer| with a new buffer. Buffers are presented in order from | 56 // Fills |out_buffer| with a new buffer. Buffers are presented in order from |
(...skipping 18 matching lines...) Expand all Loading... | |
75 // (if there are no gaps between the current position and the remaining data). | 75 // (if there are no gaps between the current position and the remaining data). |
76 bool CanEndOfStream() const; | 76 bool CanEndOfStream() const; |
77 | 77 |
78 const AudioDecoderConfig& GetCurrentAudioDecoderConfig() { | 78 const AudioDecoderConfig& GetCurrentAudioDecoderConfig() { |
79 return audio_config_; | 79 return audio_config_; |
80 } | 80 } |
81 const VideoDecoderConfig& GetCurrentVideoDecoderConfig() { | 81 const VideoDecoderConfig& GetCurrentVideoDecoderConfig() { |
82 return video_config_; | 82 return video_config_; |
83 } | 83 } |
84 | 84 |
85 base::TimeDelta max_interbuffer_distance() const { | |
86 return max_interbuffer_distance_; | |
87 } | |
88 | |
85 private: | 89 private: |
86 typedef std::list<SourceBufferRange*> RangeList; | 90 typedef std::list<SourceBufferRange*> RangeList; |
87 | 91 |
88 // Appends |new_buffers| into |range_for_new_buffers_itr|, handling start and | 92 // Appends |new_buffers| into |range_for_new_buffers_itr|, handling start and |
89 // end overlaps if necessary. | 93 // end overlaps if necessary. |
90 void InsertIntoExistingRange( | 94 void InsertIntoExistingRange( |
acolwell GONE FROM CHROMIUM
2012/07/09 18:15:55
nit: Document out parameters here too.
vrk (LEFT CHROMIUM)
2012/07/10 00:05:33
Done.
| |
91 const RangeList::iterator& range_for_new_buffers_itr, | 95 const RangeList::iterator& range_for_new_buffers_itr, |
92 const BufferQueue& new_buffers); | 96 const BufferQueue& new_buffers, |
97 bool* deleted_next_buffer, BufferQueue* deleted_buffers); | |
93 | 98 |
94 // Resolve overlapping ranges such that no ranges overlap anymore. | 99 // Resolve overlapping ranges such that no ranges overlap anymore. |
95 // |range_with_new_buffers_itr| points to the range that has newly appended | 100 // |range_with_new_buffers_itr| points to the range that has newly appended |
96 // buffers. | 101 // buffers. |
102 // |deleted_next_buffer| is an output parameter that is true if the next | |
103 // buffer that would have been returned from GetNextBuffer() was deleted | |
104 // during this call. | |
105 // |deleted_buffers| is an output parameter containing candidates for | |
106 // |track_buffer_|. | |
97 void ResolveCompleteOverlaps( | 107 void ResolveCompleteOverlaps( |
98 const RangeList::iterator& range_with_new_buffers_itr); | 108 const RangeList::iterator& range_with_new_buffers_itr, |
99 void ResolveEndOverlap(const RangeList::iterator& range_with_new_buffers_itr); | 109 bool* deleted_next_buffer, BufferQueue* deleted_buffers); |
110 void ResolveEndOverlap( | |
111 const RangeList::iterator& range_with_new_buffers_itr, | |
112 bool* deleted_next_buffer, BufferQueue* deleted_buffers); | |
100 | 113 |
101 // This method is a bit tricky to describe. When what would have been the | 114 // This method is a bit tricky to describe. When what would have been the |
102 // next buffer returned from |selected_range_| is overlapped by new data, | 115 // next buffer returned from |selected_range_| is overlapped by new data, |
103 // the |selected_range_| seeks forward to the next keyframe after (or at) the | 116 // the |selected_range_| seeks forward to the next keyframe after (or at) the |
104 // next buffer timestamp and the overlapped buffers are deleted. But for | 117 // next buffer timestamp and the overlapped buffers are deleted. But for |
105 // smooth playback between the old data to the new data's keyframe, some of | 118 // smooth playback between the old data to the new data's keyframe, some of |
106 // these |deleted_buffers| may be temporarily saved into |track_buffer_|. | 119 // these |deleted_buffers| may be temporarily saved into |track_buffer_|. |
107 // UpdateTrackBuffer() takes these |deleted_buffers| and decides whether it | 120 // UpdateTrackBuffer() takes these |deleted_buffers| and decides whether it |
108 // wants to save any buffers into |track_buffer_|. | 121 // wants to save any buffers into |track_buffer_|. |
109 // TODO(vrk): This is a little crazy! Ideas for cleanup in crbug.com/129623. | 122 // TODO(vrk): This is a little crazy! Ideas for cleanup in crbug.com/129623. |
110 void UpdateTrackBuffer(const BufferQueue& deleted_buffers); | 123 void UpdateTrackBuffer(const BufferQueue& deleted_buffers); |
111 | 124 |
112 // Checks to see if |range_with_new_buffers_itr| can be merged with the range | 125 // Checks to see if |range_with_new_buffers_itr| can be merged with the range |
113 // next to it, and merges them if so. | 126 // next to it, and merges them if so. |
114 void MergeWithAdjacentRangeIfNecessary( | 127 void MergeWithAdjacentRangeIfNecessary( |
115 const RangeList::iterator& range_with_new_buffers_itr); | 128 const RangeList::iterator& range_with_new_buffers_itr); |
116 | 129 |
117 // Helper method that returns the timestamp for the next buffer that | 130 // Helper method that returns the timestamp for the next buffer that |
118 // |selected_range_| will return from GetNextBuffer() call, or kNoTimestamp() | 131 // |selected_range_| will return from GetNextBuffer() call, or kNoTimestamp() |
119 // if in between seeking (i.e. |selected_range_| is null). | 132 // if in between seeking (i.e. |selected_range_| is null). |
120 base::TimeDelta GetNextBufferTimestamp(); | 133 base::TimeDelta GetNextBufferTimestamp(); |
121 | 134 |
122 // Finds the range into which |new_buffers| should be inserted and returns the | 135 // Returns the timestamp of the last buffer in the |selected_range_| or |
123 // iterator pointing to it. Returns |ranges_.end()| if no existing range | 136 // kNoTimestamp() if |selected_range_| is null. |
124 // should contain |new_buffers|. | 137 base::TimeDelta GetEndBufferTimestamp(); |
acolwell GONE FROM CHROMIUM
2012/07/09 18:15:55
nit: s/End/Last/ ?
vrk (LEFT CHROMIUM)
2012/07/10 00:05:33
Going to keep "End" timestamp even though it's a l
| |
125 RangeList::iterator FindExistingRangeFor(const BufferQueue& new_buffers); | 138 |
139 // Finds the range that should contain a media segment that begins with | |
140 // |start_timestamp| and returns the iterator pointing to it. Returns | |
141 // |ranges_.end()| if there's no such existing range. | |
142 RangeList::iterator FindExistingRangeFor(base::TimeDelta start_timestamp); | |
126 | 143 |
127 // Inserts |new_range| into |ranges_| preserving sorted order. Returns an | 144 // Inserts |new_range| into |ranges_| preserving sorted order. Returns an |
128 // iterator in |ranges_| that points to |new_range|. | 145 // iterator in |ranges_| that points to |new_range|. |
129 RangeList::iterator AddToRanges(SourceBufferRange* new_range); | 146 RangeList::iterator AddToRanges(SourceBufferRange* new_range); |
130 | 147 |
131 // Returns an iterator that points to the place in |ranges_| where | 148 // Returns an iterator that points to the place in |ranges_| where |
132 // |selected_range_| lives. | 149 // |selected_range_| lives. |
133 RangeList::iterator GetSelectedRangeItr(); | 150 RangeList::iterator GetSelectedRangeItr(); |
134 | 151 |
152 // Returns true if the timestamps of |buffers| are monotonically increasing | |
153 // since the previous append to the media segment, false otherwise. | |
154 bool IsMonotonicallyIncreasing(const BufferQueue& buffers); | |
155 | |
156 // Measures the distances between buffer timestamps and tracks the max. | |
157 void UpdateMaxInterbufferDistance(const BufferQueue& buffers); | |
158 | |
135 // List of disjoint buffered ranges, ordered by start time. | 159 // List of disjoint buffered ranges, ordered by start time. |
136 RangeList ranges_; | 160 RangeList ranges_; |
137 | 161 |
138 AudioDecoderConfig audio_config_; | 162 AudioDecoderConfig audio_config_; |
139 VideoDecoderConfig video_config_; | 163 VideoDecoderConfig video_config_; |
140 | 164 |
141 // True if more data needs to be appended before the Seek() can complete, | 165 // True if more data needs to be appended before the Seek() can complete, |
142 // false if no Seek() has been requested or the Seek() is completed. | 166 // false if no Seek() has been requested or the Seek() is completed. |
143 bool seek_pending_; | 167 bool seek_pending_; |
144 | 168 |
145 // Timestamp of the last request to Seek(). | 169 // Timestamp of the last request to Seek(). |
146 base::TimeDelta seek_buffer_timestamp_; | 170 base::TimeDelta seek_buffer_timestamp_; |
147 | 171 |
148 // Pointer to the seeked-to Range. This is the range from which | 172 // Pointer to the seeked-to Range. This is the range from which |
149 // GetNextBuffer() calls are fulfilled after the |track_buffer_| has been | 173 // GetNextBuffer() calls are fulfilled after the |track_buffer_| has been |
150 // emptied. | 174 // emptied. |
151 SourceBufferRange* selected_range_; | 175 SourceBufferRange* selected_range_; |
152 | 176 |
153 // Queue of the next buffers to be returned from calls to GetNextBuffer(). If | 177 // Queue of the next buffers to be returned from calls to GetNextBuffer(). If |
154 // |track_buffer_| is empty, return buffers from |selected_range_|. | 178 // |track_buffer_| is empty, return buffers from |selected_range_|. |
155 BufferQueue track_buffer_; | 179 BufferQueue track_buffer_; |
156 | 180 |
157 // True when EndOfStream() has been called and GetNextBuffer() should return | 181 // True when EndOfStream() has been called and GetNextBuffer() should return |
158 // EOS buffers for read requests beyond the buffered data. False initially. | 182 // EOS buffers for read requests beyond the buffered data. False initially. |
159 bool end_of_stream_; | 183 bool end_of_stream_; |
160 | 184 |
185 // The start time of the current media segment being appended. | |
186 base::TimeDelta media_segment_start_time_; | |
187 | |
188 // Points to the range containing the current media segment being appended. | |
189 RangeList::iterator range_for_next_append_; | |
190 | |
191 // True when the next call to Append() begins a new media segment. | |
192 bool new_media_segment_; | |
193 | |
194 // The timestamp of the last buffer appended to the media segment, set to | |
195 // kNoTimestamp() if the beginning of the segment. | |
196 base::TimeDelta last_buffer_timestamp_; | |
197 | |
198 // Stores the largest distance between two adjacent buffers in this stream. | |
199 base::TimeDelta max_interbuffer_distance_; | |
200 | |
161 DISALLOW_COPY_AND_ASSIGN(SourceBufferStream); | 201 DISALLOW_COPY_AND_ASSIGN(SourceBufferStream); |
162 }; | 202 }; |
163 | 203 |
164 } // namespace media | 204 } // namespace media |
165 | 205 |
166 #endif // MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ | 206 #endif // MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ |
OLD | NEW |