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 // Returns the largest distance between two adjacent buffers in this stream, |
| 86 // or an estimate if no two adjacent buffers have been appended to the stream |
| 87 // yet. |
| 88 base::TimeDelta GetMaxInterbufferDistance() const; |
| 89 |
85 private: | 90 private: |
86 typedef std::list<SourceBufferRange*> RangeList; | 91 typedef std::list<SourceBufferRange*> RangeList; |
87 | 92 |
88 // Appends |new_buffers| into |range_for_new_buffers_itr|, handling start and | 93 // Appends |new_buffers| into |range_for_new_buffers_itr|, handling start and |
89 // end overlaps if necessary. | 94 // end overlaps if necessary. |
| 95 // |deleted_next_buffer| is an output parameter that is true if the next |
| 96 // buffer that would have been returned from GetNextBuffer() was deleted |
| 97 // during this call. |
| 98 // |deleted_buffers| is an output parameter containing candidates for |
| 99 // |track_buffer_|. |
90 void InsertIntoExistingRange( | 100 void InsertIntoExistingRange( |
91 const RangeList::iterator& range_for_new_buffers_itr, | 101 const RangeList::iterator& range_for_new_buffers_itr, |
92 const BufferQueue& new_buffers); | 102 const BufferQueue& new_buffers, |
| 103 bool* deleted_next_buffer, BufferQueue* deleted_buffers); |
93 | 104 |
94 // Resolve overlapping ranges such that no ranges overlap anymore. | 105 // Resolve overlapping ranges such that no ranges overlap anymore. |
95 // |range_with_new_buffers_itr| points to the range that has newly appended | 106 // |range_with_new_buffers_itr| points to the range that has newly appended |
96 // buffers. | 107 // buffers. |
| 108 // |deleted_next_buffer| is an output parameter that is true if the next |
| 109 // buffer that would have been returned from GetNextBuffer() was deleted |
| 110 // during this call. |
| 111 // |deleted_buffers| is an output parameter containing candidates for |
| 112 // |track_buffer_|. |
97 void ResolveCompleteOverlaps( | 113 void ResolveCompleteOverlaps( |
98 const RangeList::iterator& range_with_new_buffers_itr); | 114 const RangeList::iterator& range_with_new_buffers_itr, |
99 void ResolveEndOverlap(const RangeList::iterator& range_with_new_buffers_itr); | 115 bool* deleted_next_buffer, BufferQueue* deleted_buffers); |
| 116 void ResolveEndOverlap( |
| 117 const RangeList::iterator& range_with_new_buffers_itr, |
| 118 bool* deleted_next_buffer, BufferQueue* deleted_buffers); |
100 | 119 |
101 // This method is a bit tricky to describe. When what would have been the | 120 // 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, | 121 // 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 | 122 // 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 | 123 // 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 | 124 // 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_|. | 125 // these |deleted_buffers| may be temporarily saved into |track_buffer_|. |
107 // UpdateTrackBuffer() takes these |deleted_buffers| and decides whether it | 126 // UpdateTrackBuffer() takes these |deleted_buffers| and decides whether it |
108 // wants to save any buffers into |track_buffer_|. | 127 // wants to save any buffers into |track_buffer_|. |
109 // TODO(vrk): This is a little crazy! Ideas for cleanup in crbug.com/129623. | 128 // TODO(vrk): This is a little crazy! Ideas for cleanup in crbug.com/129623. |
110 void UpdateTrackBuffer(const BufferQueue& deleted_buffers); | 129 void UpdateTrackBuffer(const BufferQueue& deleted_buffers); |
111 | 130 |
112 // Checks to see if |range_with_new_buffers_itr| can be merged with the range | 131 // Checks to see if |range_with_new_buffers_itr| can be merged with the range |
113 // next to it, and merges them if so. | 132 // next to it, and merges them if so. |
114 void MergeWithAdjacentRangeIfNecessary( | 133 void MergeWithAdjacentRangeIfNecessary( |
115 const RangeList::iterator& range_with_new_buffers_itr); | 134 const RangeList::iterator& range_with_new_buffers_itr); |
116 | 135 |
117 // Helper method that returns the timestamp for the next buffer that | 136 // Helper method that returns the timestamp for the next buffer that |
118 // |selected_range_| will return from GetNextBuffer() call, or kNoTimestamp() | 137 // |selected_range_| will return from GetNextBuffer() call, or kNoTimestamp() |
119 // if in between seeking (i.e. |selected_range_| is null). | 138 // if in between seeking (i.e. |selected_range_| is null). |
120 base::TimeDelta GetNextBufferTimestamp(); | 139 base::TimeDelta GetNextBufferTimestamp(); |
121 | 140 |
122 // Finds the range into which |new_buffers| should be inserted and returns the | 141 // Returns the timestamp of the last buffer in the |selected_range_| or |
123 // iterator pointing to it. Returns |ranges_.end()| if no existing range | 142 // kNoTimestamp() if |selected_range_| is null. |
124 // should contain |new_buffers|. | 143 base::TimeDelta GetEndBufferTimestamp(); |
125 RangeList::iterator FindExistingRangeFor(const BufferQueue& new_buffers); | 144 |
| 145 // Finds the range that should contain a media segment that begins with |
| 146 // |start_timestamp| and returns the iterator pointing to it. Returns |
| 147 // |ranges_.end()| if there's no such existing range. |
| 148 RangeList::iterator FindExistingRangeFor(base::TimeDelta start_timestamp); |
126 | 149 |
127 // Inserts |new_range| into |ranges_| preserving sorted order. Returns an | 150 // Inserts |new_range| into |ranges_| preserving sorted order. Returns an |
128 // iterator in |ranges_| that points to |new_range|. | 151 // iterator in |ranges_| that points to |new_range|. |
129 RangeList::iterator AddToRanges(SourceBufferRange* new_range); | 152 RangeList::iterator AddToRanges(SourceBufferRange* new_range); |
130 | 153 |
131 // Returns an iterator that points to the place in |ranges_| where | 154 // Returns an iterator that points to the place in |ranges_| where |
132 // |selected_range_| lives. | 155 // |selected_range_| lives. |
133 RangeList::iterator GetSelectedRangeItr(); | 156 RangeList::iterator GetSelectedRangeItr(); |
134 | 157 |
| 158 // Returns true if the timestamps of |buffers| are monotonically increasing |
| 159 // since the previous append to the media segment, false otherwise. |
| 160 bool IsMonotonicallyIncreasing(const BufferQueue& buffers); |
| 161 |
| 162 // Measures the distances between buffer timestamps and tracks the max. |
| 163 void UpdateMaxInterbufferDistance(const BufferQueue& buffers); |
| 164 |
135 // List of disjoint buffered ranges, ordered by start time. | 165 // List of disjoint buffered ranges, ordered by start time. |
136 RangeList ranges_; | 166 RangeList ranges_; |
137 | 167 |
138 AudioDecoderConfig audio_config_; | 168 AudioDecoderConfig audio_config_; |
139 VideoDecoderConfig video_config_; | 169 VideoDecoderConfig video_config_; |
140 | 170 |
141 // True if more data needs to be appended before the Seek() can complete, | 171 // 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. | 172 // false if no Seek() has been requested or the Seek() is completed. |
143 bool seek_pending_; | 173 bool seek_pending_; |
144 | 174 |
145 // Timestamp of the last request to Seek(). | 175 // Timestamp of the last request to Seek(). |
146 base::TimeDelta seek_buffer_timestamp_; | 176 base::TimeDelta seek_buffer_timestamp_; |
147 | 177 |
148 // Pointer to the seeked-to Range. This is the range from which | 178 // Pointer to the seeked-to Range. This is the range from which |
149 // GetNextBuffer() calls are fulfilled after the |track_buffer_| has been | 179 // GetNextBuffer() calls are fulfilled after the |track_buffer_| has been |
150 // emptied. | 180 // emptied. |
151 SourceBufferRange* selected_range_; | 181 SourceBufferRange* selected_range_; |
152 | 182 |
153 // Queue of the next buffers to be returned from calls to GetNextBuffer(). If | 183 // Queue of the next buffers to be returned from calls to GetNextBuffer(). If |
154 // |track_buffer_| is empty, return buffers from |selected_range_|. | 184 // |track_buffer_| is empty, return buffers from |selected_range_|. |
155 BufferQueue track_buffer_; | 185 BufferQueue track_buffer_; |
156 | 186 |
157 // True when EndOfStream() has been called and GetNextBuffer() should return | 187 // True when EndOfStream() has been called and GetNextBuffer() should return |
158 // EOS buffers for read requests beyond the buffered data. False initially. | 188 // EOS buffers for read requests beyond the buffered data. False initially. |
159 bool end_of_stream_; | 189 bool end_of_stream_; |
160 | 190 |
| 191 // The start time of the current media segment being appended. |
| 192 base::TimeDelta media_segment_start_time_; |
| 193 |
| 194 // Points to the range containing the current media segment being appended. |
| 195 RangeList::iterator range_for_next_append_; |
| 196 |
| 197 // True when the next call to Append() begins a new media segment. |
| 198 bool new_media_segment_; |
| 199 |
| 200 // The timestamp of the last buffer appended to the media segment, set to |
| 201 // kNoTimestamp() if the beginning of the segment. |
| 202 base::TimeDelta last_buffer_timestamp_; |
| 203 |
| 204 // Stores the largest distance between two adjacent buffers in this stream. |
| 205 base::TimeDelta max_interbuffer_distance_; |
| 206 |
161 DISALLOW_COPY_AND_ASSIGN(SourceBufferStream); | 207 DISALLOW_COPY_AND_ASSIGN(SourceBufferStream); |
162 }; | 208 }; |
163 | 209 |
164 } // namespace media | 210 } // namespace media |
165 | 211 |
166 #endif // MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ | 212 #endif // MEDIA_FILTERS_SOURCE_BUFFER_STREAM_H_ |
OLD | NEW |