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
14namespace 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.
19class 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