1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_FILTERS_SOURCE_BUFFER_RANGE_H_ 6 #define MEDIA_FILTERS_SOURCE_BUFFER_RANGE_H_ 7 8 #include <map> 9 10 #include "base/callback.h" 11 #include "base/memory/ref_counted.h" 12 #include "media/base/stream_parser_buffer.h" 13 14 namespace media { 15 16 // Helper class representing a range of buffered data. All buffers in a 17 // SourceBufferRange are ordered sequentially in decode timestamp order with no 18 // gaps. 19 class SourceBufferRange { 20 public: 21 // Returns the maximum distance in time between any buffer seen in this 22 // stream. Used to estimate the duration of a buffer if its duration is not 23 // known. 24 typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB; 25 26 typedef StreamParser::BufferQueue BufferQueue; 27 28 // Policy for handling large gaps between buffers. Continuous media like 29 // audio & video should use NO_GAPS_ALLOWED. Discontinuous media like 30 // timed text should use ALLOW_GAPS because large differences in timestamps 31 // are common and acceptable. 32 enum GapPolicy { 33 NO_GAPS_ALLOWED, 34 ALLOW_GAPS 35 }; 36 37 // Buffers with the same timestamp are only allowed under certain conditions. 38 // More precisely, it is allowed in all situations except when the previous 39 // frame is not a key frame and the current is a key frame. 40 // Examples of situations where DTS of two consecutive frames can be equal: 41 // - Video: VP8 Alt-Ref frames. 42 // - Video: IPBPBP...: DTS for I frame and for P frame can be equal. 43 // - Text track cues that start at same time. 44 // Returns true if |prev_is_keyframe| and |current_is_keyframe| indicate a 45 // same timestamp situation that is allowed. False is returned otherwise. 46 static bool AllowSameTimestamp(bool prev_is_keyframe, 47 bool current_is_keyframe); 48 49 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be 50 // empty and the front of |new_buffers| must be a keyframe. 51 // |media_segment_start_time| refers to the starting timestamp for the media 52 // segment to which these buffers belong. 53 SourceBufferRange(GapPolicy gap_policy, 54 const BufferQueue& new_buffers, 55 DecodeTimestamp media_segment_start_time, 56 const InterbufferDistanceCB& interbuffer_distance_cb); 57 58 ~SourceBufferRange(); 59 60 // Appends |buffers| to the end of the range and updates |keyframe_map_| as 61 // it encounters new keyframes. Assumes |buffers| belongs at the end of the 62 // range. 63 void AppendBuffersToEnd(const BufferQueue& buffers); 64 bool CanAppendBuffersToEnd(const BufferQueue& buffers) const; 65 66 // Appends the buffers from |range| into this range. 67 // The first buffer in |range| must come directly after the last buffer 68 // in this range. 69 // If |transfer_current_position| is true, |range|'s |next_buffer_index_| 70 // is transfered to this SourceBufferRange. 71 void AppendRangeToEnd(const SourceBufferRange& range, 72 bool transfer_current_position); 73 bool CanAppendRangeToEnd(const SourceBufferRange& range) const; 74 75 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|. 76 // Assumes |timestamp| is valid and in this range. 77 void Seek(DecodeTimestamp timestamp); 78 79 // Updates |next_buffer_index_| to point to next keyframe after or equal to 80 // |timestamp|. 81 void SeekAheadTo(DecodeTimestamp timestamp); 82 83 // Updates |next_buffer_index_| to point to next keyframe strictly after 84 // |timestamp|. 85 void SeekAheadPast(DecodeTimestamp timestamp); 86 87 // Seeks to the beginning of the range. 88 void SeekToStart(); 89 90 // Finds the next keyframe from |buffers_| after |timestamp| (or at 91 // |timestamp| if |is_exclusive| is false) and creates and returns a new 92 // SourceBufferRange with the buffers from that keyframe onward. 93 // The buffers in the new SourceBufferRange are moved out of this range. If 94 // there is no keyframe after |timestamp|, SplitRange() returns null and this 95 // range is unmodified. 96 SourceBufferRange* SplitRange(DecodeTimestamp timestamp, bool is_exclusive); 97 98 // Deletes the buffers from this range starting at |timestamp|, exclusive if 99 // |is_exclusive| is true, inclusive otherwise. 100 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was 101 // deleted, and deletes the |keyframe_map_| entries for the buffers that 102 // were removed. 103 // |deleted_buffers| contains the buffers that were deleted from this range, 104 // starting at the buffer that had been at |next_buffer_index_|. 105 // Returns true if everything in the range was deleted. Otherwise 106 // returns false. 107 bool TruncateAt(DecodeTimestamp timestamp, 108 BufferQueue* deleted_buffers, bool is_exclusive); 109 // Deletes all buffers in range. 110 void DeleteAll(BufferQueue* deleted_buffers); 111 112 // Deletes a GOP from the front or back of the range and moves these 113 // buffers into |deleted_buffers|. Returns the number of bytes deleted from 114 // the range (i.e. the size in bytes of |deleted_buffers|). 115 int DeleteGOPFromFront(BufferQueue* deleted_buffers); 116 int DeleteGOPFromBack(BufferQueue* deleted_buffers); 117 118 // Gets the range of GOP to secure at least |bytes_to_free| from 119 // [|start_timestamp|, |end_timestamp|). 120 // Returns the size of the buffers to secure if the buffers of 121 // [|start_timestamp|, |end_removal_timestamp|) is removed. 122 // Will not update |end_removal_timestamp| if the returned size is 0. 123 int GetRemovalGOP( 124 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, 125 int bytes_to_free, DecodeTimestamp* end_removal_timestamp); 126 127 // Indicates whether the GOP at the beginning or end of the range contains the 128 // next buffer position. 129 bool FirstGOPContainsNextBufferPosition() const; 130 bool LastGOPContainsNextBufferPosition() const; 131 132 // Updates |out_buffer| with the next buffer in presentation order. Seek() 133 // must be called before calls to GetNextBuffer(), and buffers are returned 134 // in order from the last call to Seek(). Returns true if |out_buffer| is 135 // filled with a valid buffer, false if there is not enough data to fulfill 136 // the request. 137 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer); 138 bool HasNextBuffer() const; 139 140 // Returns the config ID for the buffer that will be returned by 141 // GetNextBuffer(). 142 int GetNextConfigId() const; 143 144 // Returns true if the range knows the position of the next buffer it should 145 // return, i.e. it has been Seek()ed. This does not necessarily mean that it 146 // has the next buffer yet. 147 bool HasNextBufferPosition() const; 148 149 // Resets this range to an "unseeked" state. 150 void ResetNextBufferPosition(); 151 152 // Returns the timestamp of the next buffer that will be returned from 153 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown. 154 DecodeTimestamp GetNextTimestamp() const; 155 156 // Returns the start timestamp of the range. 157 DecodeTimestamp GetStartTimestamp() const; 158 159 // Returns the timestamp of the last buffer in the range. 160 DecodeTimestamp GetEndTimestamp() const; 161 162 // Returns the timestamp for the end of the buffered region in this range. 163 // This is an approximation if the duration for the last buffer in the range 164 // is unset. 165 DecodeTimestamp GetBufferedEndTimestamp() const; 166 167 // Gets the timestamp for the keyframe that is after |timestamp|. If 168 // there isn't a keyframe in the range after |timestamp| then kNoTimestamp() 169 // is returned. If |timestamp| is in the "gap" between the value returned by 170 // GetStartTimestamp() and the timestamp on the first buffer in |buffers_|, 171 // then |timestamp| is returned. 172 DecodeTimestamp NextKeyframeTimestamp(DecodeTimestamp timestamp); 173 174 // Gets the timestamp for the closest keyframe that is <= |timestamp|. If 175 // there isn't a keyframe before |timestamp| or |timestamp| is outside 176 // this range, then kNoTimestamp() is returned. 177 DecodeTimestamp KeyframeBeforeTimestamp(DecodeTimestamp timestamp); 178 179 // Returns whether a buffer with a starting timestamp of |timestamp| would 180 // belong in this range. This includes a buffer that would be appended to 181 // the end of the range. 182 bool BelongsToRange(DecodeTimestamp timestamp) const; 183 184 // Returns true if the range has enough data to seek to the specified 185 // |timestamp|, false otherwise. 186 bool CanSeekTo(DecodeTimestamp timestamp) const; 187 188 // Returns true if this range's buffered timespan completely overlaps the 189 // buffered timespan of |range|. 190 bool CompletelyOverlaps(const SourceBufferRange& range) const; 191 192 // Returns true if the end of this range contains buffers that overlaps with 193 // the beginning of |range|. 194 bool EndOverlaps(const SourceBufferRange& range) const; 195 196 // Returns true if |timestamp| is the timestamp of the next buffer in 197 // sequence after |buffers_.back()|, false otherwise. 198 bool IsNextInSequence(DecodeTimestamp timestamp, bool is_keyframe) const; 199 200 // Adds all buffers which overlap [start, end) to the end of |buffers|. If 201 // no buffers exist in the range returns false, true otherwise. 202 bool GetBuffersInRange(DecodeTimestamp start, DecodeTimestamp end, 203 BufferQueue* buffers); 204 205 int size_in_bytes() const { return size_in_bytes_; } 206 207 private: 208 typedef std::map<DecodeTimestamp, int> KeyframeMap; 209 210 // Seeks the range to the next keyframe after |timestamp|. If 211 // |skip_given_timestamp| is true, the seek will go to a keyframe with a 212 // timestamp strictly greater than |timestamp|. 213 void SeekAhead(DecodeTimestamp timestamp, bool skip_given_timestamp); 214 215 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|. 216 // If |skip_given_timestamp| is true, this returns the first buffer with 217 // timestamp greater than |timestamp|. 218 BufferQueue::iterator GetBufferItrAt( 219 DecodeTimestamp timestamp, bool skip_given_timestamp); 220 221 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after 222 // |timestamp|. If |skip_given_timestamp| is true, this returns the first 223 // keyframe with a timestamp strictly greater than |timestamp|. 224 KeyframeMap::iterator GetFirstKeyframeAt( 225 DecodeTimestamp timestamp, bool skip_given_timestamp); 226 227 // Returns an iterator in |keyframe_map_| pointing to the first keyframe 228 // before or at |timestamp|. 229 KeyframeMap::iterator GetFirstKeyframeBefore(DecodeTimestamp timestamp); 230 231 // Helper method to delete buffers in |buffers_| starting at 232 // |starting_point|, an iterator in |buffers_|. 233 // Returns true if everything in the range was removed. Returns 234 // false if the range still contains buffers. 235 bool TruncateAt(const BufferQueue::iterator& starting_point, 236 BufferQueue* deleted_buffers); 237 238 // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and 239 // updates the |size_in_bytes_| accordingly. Does not update |keyframe_map_|. 240 void FreeBufferRange(const BufferQueue::iterator& starting_point, 241 const BufferQueue::iterator& ending_point); 242 243 // Returns the distance in time estimating how far from the beginning or end 244 // of this range a buffer can be to considered in the range. 245 base::TimeDelta GetFudgeRoom() const; 246 247 // Returns the approximate duration of a buffer in this range. 248 base::TimeDelta GetApproximateDuration() const; 249 250 // Keeps track of whether gaps are allowed. 251 const GapPolicy gap_policy_; 252 253 // An ordered list of buffers in this range. 254 BufferQueue buffers_; 255 256 // Maps keyframe timestamps to its index position in |buffers_|. 257 KeyframeMap keyframe_map_; 258 259 // Index base of all positions in |keyframe_map_|. In other words, the 260 // real position of entry |k| of |keyframe_map_| in the range is: 261 // keyframe_map_[k] - keyframe_map_index_base_ 262 int keyframe_map_index_base_; 263 264 // Index into |buffers_| for the next buffer to be returned by 265 // GetNextBuffer(), set to -1 before Seek(). 266 int next_buffer_index_; 267 268 // If the first buffer in this range is the beginning of a media segment, 269 // |media_segment_start_time_| is the time when the media segment begins. 270 // |media_segment_start_time_| may be <= the timestamp of the first buffer in 271 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range 272 // does not start at the beginning of a media segment, which can only happen 273 // garbage collection or after an end overlap that results in a split range 274 // (we don't have a way of knowing the media segment timestamp for the new 275 // range). 276 DecodeTimestamp media_segment_start_time_; 277 278 // Called to get the largest interbuffer distance seen so far in the stream. 279 InterbufferDistanceCB interbuffer_distance_cb_; 280 281 // Stores the amount of memory taken up by the data in |buffers_|. 282 int size_in_bytes_; 283 284 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange); 285 }; 286 287 } // namespace media 288 289 #endif // MEDIA_FILTERS_SOURCE_BUFFER_RANGE_H_ 290