Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / source_buffer_range.h
1 // Copyright 2014 The Chromium Authors
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 <stddef.h>
9 #include <map>
10 #include <memory>
11
12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/time/time.h"
15 #include "media/base/media_export.h"
16 #include "media/base/stream_parser_buffer.h"
17
18 namespace media {
19
20 // Base class for representing a continuous range of buffered data in the
21 // presentation timeline. All buffers in a SourceBufferRange are ordered
22 // sequentially by GOP presentation interval, and within each GOP by decode
23 // order. Unless constructed with |ALLOW_GAPS|, the range contains no internal
24 // presentation gaps.
25 class MEDIA_EXPORT SourceBufferRange {
26  public:
27   // Returns the maximum distance in time between any buffer seen in the stream
28   // of which this range is a part. Used to estimate the duration of a buffer if
29   // its duration is not known, and in GetFudgeRoom() for determining whether a
30   // time or coded frame is close enough to be considered part of this range.
31   using InterbufferDistanceCB = base::RepeatingCallback<base::TimeDelta()>;
32
33   using BufferQueue = StreamParser::BufferQueue;
34
35   // Policy for handling large gaps between buffers. Continuous media like
36   // audio & video should use NO_GAPS_ALLOWED. Discontinuous media like
37   // timed text should use ALLOW_GAPS because large differences in timestamps
38   // are common and acceptable.
39   enum GapPolicy {
40     NO_GAPS_ALLOWED,
41     ALLOW_GAPS
42   };
43
44   // Creates a range with |new_buffers|. |new_buffers| cannot be empty and the
45   // front of |new_buffers| must be a keyframe.
46   // |range_start_pts| refers to the starting timestamp for the coded
47   // frame group to which these buffers belong.
48   SourceBufferRange(GapPolicy gap_policy,
49                     const BufferQueue& new_buffers,
50                     base::TimeDelta range_start_pts,
51                     InterbufferDistanceCB interbuffer_distance_cb);
52
53   SourceBufferRange(const SourceBufferRange&) = delete;
54   SourceBufferRange& operator=(const SourceBufferRange&) = delete;
55
56   ~SourceBufferRange();
57
58   // Deletes all buffers in range.
59   void DeleteAll(BufferQueue* deleted_buffers);
60
61   // Seeks to the beginning of the range.
62   void SeekToStart();
63
64   // Updates |out_buffer| with the next buffer in presentation order by GOP and
65   // by decode order within each GOP (in general, in sequence to feed a
66   // decoder). Seek() must be called before calls to GetNextBuffer(), and
67   // buffers are returned in order from the last call to Seek(). Returns true if
68   // |out_buffer| is filled with a valid buffer, false if there is not enough
69   // data to fulfill the request.
70   bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
71   bool HasNextBuffer() const;
72
73   // Returns the config ID for the buffer that will be returned by
74   // GetNextBuffer().
75   int GetNextConfigId() const;
76
77   // Returns true if the range knows the position of the next buffer it should
78   // return, i.e. it has been Seek()ed. This does not necessarily mean that it
79   // has the next buffer yet.
80   bool HasNextBufferPosition() const;
81
82   // Resets this range to an "unseeked" state.
83   void ResetNextBufferPosition();
84
85   // Appends the buffers from |range| into this range.
86   // The first buffer in |range| must come directly after the last buffer
87   // in this range.
88   // If |transfer_current_position| is true, |range|'s |next_buffer_index_|
89   // is transferred to this SourceBufferRange.
90   // Note: Use these only to merge existing ranges. |range|'s first buffer
91   // timestamp must be adjacent to this range. No group start timestamp
92   // adjacency is involved in these methods.
93   // During append, |highest_frame_| is updated, if necessary.
94   void AppendRangeToEnd(const SourceBufferRange& range,
95                         bool transfer_current_position);
96   bool CanAppendRangeToEnd(const SourceBufferRange& range) const;
97
98   // Appends |buffers| to the end of the range and updates |keyframe_map_| as
99   // it encounters new keyframes.
100   // If |new_buffers_group_start_pts| is kNoTimestamp, then the
101   // first buffer in |buffers| must come directly after the last buffer in this
102   // range (within the fudge room) - specifically, if the first buffer in
103   // |buffers| is not a keyframe, then it must be next in DTS order w.r.t. last
104   // buffer in |buffers|. Otherwise, it's a keyframe that must be next in PTS
105   // order w.r.t. |highest_frame_| or be immediately adjacent to the last buffer
106   // in this range if that buffer has estimated duration (only allowed in WebM
107   // streams).
108   // If |new_buffers_group_start_pts| is set otherwise, then that time must come
109   // directly after |highest_frame_| (within the fudge room), or directly after
110   // the last buffered frame if it has estimated duration (only allowed in WebM
111   // streams), and the first buffer in |buffers| must be a keyframe.
112   // The latter scenario is required when a muxed coded frame group has such a
113   // large jagged start across tracks that its first buffer is not within the
114   // fudge room, yet its group start was.
115   // The conditions around estimated duration are handled by
116   // AllowableAppendAfterEstimatedDuration, and are intended to solve the edge
117   // case in the SourceBufferStreamTest
118   // MergeAllowedIfRangeEndTimeWithEstimatedDurationMatchesNextRangeStart.
119   // During append, |highest_frame_| is updated, if necessary.
120   void AppendBuffersToEnd(const BufferQueue& buffers,
121                           base::TimeDelta new_buffers_group_start_timestamp);
122   bool AllowableAppendAfterEstimatedDuration(
123       const BufferQueue& buffers,
124       base::TimeDelta new_buffers_group_start_pts) const;
125   bool CanAppendBuffersToEnd(const BufferQueue& buffers,
126                              base::TimeDelta new_buffers_group_start_pts) const;
127
128   // Updates |next_buffer_index_| to point to the keyframe with presentation
129   // timestamp at or before |timestamp|. Assumes |timestamp| is valid and in
130   // this range.
131   void Seek(base::TimeDelta timestamp);
132
133   // Returns true if the range has enough data to seek to the specified
134   // |timestamp|, false otherwise.
135   bool CanSeekTo(base::TimeDelta timestamp) const;
136
137   // Return the config ID for the buffer at |timestamp|. Precondition: callers
138   // must first verify CanSeekTo(timestamp) == true.
139   int GetConfigIdAtTime(base::TimeDelta timestamp) const;
140
141   // Return true if all buffers in range of [start, end] have the same config
142   // ID. Precondition: callers must first verify that
143   // CanSeekTo(start) ==  CanSeekTo(end) == true.
144   bool SameConfigThruRange(base::TimeDelta start, base::TimeDelta end) const;
145
146   // Finds the next keyframe from |buffers_| starting at or after |timestamp|
147   // and creates and returns a new SourceBufferRange with the buffers from
148   // that keyframe onward. The buffers in the new SourceBufferRange are
149   // moved out of this range. The start time of the new SourceBufferRange
150   // is set to the later of |timestamp| and this range's GetStartTimestamp().
151   // Note that this may result in temporary overlap of the new range and this
152   // range until the caller truncates any nonkeyframes out of this range with
153   // time > |timestamp|.  If there is no keyframe at or after |timestamp|,
154   // SplitRange() returns null and this range is unmodified. This range can
155   // become empty if |timestamp| <= the PTS of the first buffer in this range.
156   // |highest_frame_| is updated, if necessary.
157   std::unique_ptr<SourceBufferRange> SplitRange(base::TimeDelta timestamp);
158
159   // Deletes the buffers from this range starting at |timestamp|, exclusive if
160   // |is_exclusive| is true, inclusive otherwise.
161   // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
162   // deleted, and deletes the |keyframe_map_| entries for the buffers that
163   // were removed.
164   // |highest_frame_| is updated, if necessary.
165   // |deleted_buffers| contains the buffers that were deleted from this range,
166   // starting at the buffer that had been at |next_buffer_index_|.
167   // Returns true if everything in the range was deleted. Otherwise
168   // returns false.
169   bool TruncateAt(base::TimeDelta timestamp,
170                   BufferQueue* deleted_buffers,
171                   bool is_exclusive);
172
173   // Deletes a GOP from the front or back of the range and moves these
174   // buffers into |deleted_buffers|. Returns the number of bytes deleted from
175   // the range (i.e. the size in bytes of |deleted_buffers|).
176   // |highest_frame_| is updated, if necessary.
177   // This range must NOT be empty when these methods are called.
178   // The GOP being deleted must NOT contain the next buffer position.
179   size_t DeleteGOPFromFront(BufferQueue* deleted_buffers);
180   size_t DeleteGOPFromBack(BufferQueue* deleted_buffers);
181
182   // Gets the range of GOP to secure at least |bytes_to_free| from
183   // [|start_timestamp|, |end_timestamp|).
184   // Returns the size of the buffers to secure if the buffers of
185   // [|start_timestamp|, |end_removal_timestamp|) is removed.
186   // Will not update |end_removal_timestamp| if the returned size is 0.
187   size_t GetRemovalGOP(base::TimeDelta start_timestamp,
188                        base::TimeDelta end_timestamp,
189                        size_t bytes_to_free,
190                        base::TimeDelta* end_removal_timestamp) const;
191
192   // Returns true iff the buffered end time of the first GOP in this range is
193   // at or before |media_time|.
194   bool FirstGOPEarlierThanMediaTime(base::TimeDelta media_time) const;
195
196   // Indicates whether the GOP at the beginning or end of the range contains the
197   // next buffer position.
198   bool FirstGOPContainsNextBufferPosition() const;
199   bool LastGOPContainsNextBufferPosition() const;
200
201   // Returns the timestamp of the next buffer that will be returned from
202   // GetNextBuffer(), or kNoTimestamp if the timestamp is unknown.
203   base::TimeDelta GetNextTimestamp() const;
204
205   // Returns the start timestamp of the range.
206   base::TimeDelta GetStartTimestamp() const;
207
208   // Returns the highest presentation timestamp of frames in the last GOP in the
209   // range.
210   base::TimeDelta GetEndTimestamp() const;
211
212   // Returns the timestamp for the end of the buffered region in this range.
213   // This is an approximation if the duration for the buffer with highest PTS in
214   // the last GOP in the range is unset.
215   base::TimeDelta GetBufferedEndTimestamp() const;
216
217   // Returns whether a buffer with a starting timestamp of |timestamp| would
218   // belong in this range. This includes a buffer that would be appended to
219   // the end of the range.
220   bool BelongsToRange(base::TimeDelta timestamp) const;
221
222   // Returns the highest time from among GetStartTimestamp() and frame timestamp
223   // (in order in |buffers_| beginning at the first keyframe at or before
224   // |timestamp|) for buffers in this range up to and including |timestamp|.
225   // Note that |timestamp| must belong to this range.
226   base::TimeDelta FindHighestBufferedTimestampAtOrBefore(
227       base::TimeDelta timestamp) const;
228
229   // Gets the timestamp for the keyframe that is at or after |timestamp|. If
230   // there isn't such a keyframe in the range then kNoTimestamp is returned.
231   // If |timestamp| is in the "gap" between the value returned by
232   // GetStartTimestamp() and the timestamp on the first buffer in |buffers_|,
233   // then |timestamp| is returned.
234   base::TimeDelta NextKeyframeTimestamp(base::TimeDelta timestamp) const;
235
236   // Gets the timestamp for the closest keyframe that is <= |timestamp|. If
237   // there isn't a keyframe before |timestamp| or |timestamp| is outside
238   // this range, then kNoTimestamp is returned.
239   base::TimeDelta KeyframeBeforeTimestamp(base::TimeDelta timestamp) const;
240
241   // Adds all buffers which overlap [start, end) to the end of |buffers|. If no
242   // buffers exist in the range returns false, true otherwise.  This method is
243   // only used for finding audio splice overlap buffers, so all buffers are
244   // expected to be keyframes here, or if not keyframes, to at least be in PTS
245   // order since the previous keyframe.
246   bool GetBuffersInRange(base::TimeDelta start,
247                          base::TimeDelta end,
248                          BufferQueue* buffers) const;
249
250   size_t size_in_bytes() const { return size_in_bytes_; }
251
252  private:
253   // Friend of private is only for IsNextInPresentationSequence testing.
254   friend class SourceBufferStreamTest;
255
256   using KeyframeMap = std::map<base::TimeDelta, int>;
257
258   // Called during AppendBuffersToEnd to adjust estimated duration at the
259   // end of the last append to match the delta in timestamps between
260   // the last append and the upcoming append. This is a workaround for
261   // WebM media where a duration is not always specified. Caller should take
262   // care of updating |highest_frame_|.
263   void AdjustEstimatedDurationForNewAppend(const BufferQueue& new_buffers);
264
265   // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and
266   // updates the |size_in_bytes_| accordingly. Note, this does not update
267   // |keyframe_map_|.
268   void FreeBufferRange(const BufferQueue::const_iterator& starting_point,
269                        const BufferQueue::const_iterator& ending_point);
270
271   // Returns the distance in time estimating how far from the beginning or end
272   // of this range a buffer can be to be considered in the range.
273   base::TimeDelta GetFudgeRoom() const;
274
275   // Returns the approximate duration of a buffer in this range.
276   base::TimeDelta GetApproximateDuration() const;
277
278   // Updates |highest_frame_| if |new_buffer| has a higher PTS than
279   // |highest_frame_|, |new_buffer| has the same PTS as |highest_frame_| and
280   // duration at least as long as |highest_frame_|, or if the range was
281   // previously empty.
282   void UpdateEndTime(scoped_refptr<StreamParserBuffer> new_buffer);
283
284   // Returns true if |timestamp| is allowed in this range as the timestamp of
285   // the next buffer in presentation sequence at or after |highest_frame_|.
286   // |buffers_| must not be empty, and |highest_frame_| must not be nullptr.
287   // Uses |gap_policy_| to potentially allow gaps.
288   //
289   // Due to potential for out-of-order decode vs presentation time, this method
290   // should only be used to determine adjacency of keyframes with the end of
291   // |buffers_|.
292   bool IsNextInPresentationSequence(base::TimeDelta timestamp) const;
293
294   // Returns true if |decode_timestamp| is allowed in this range as the decode
295   // timestamp of the next buffer in decode sequence at or after the last buffer
296   // in |buffers_|'s decode timestamp.  |buffers_| must not be empty. Uses
297   // |gap_policy_| to potentially allow gaps.
298   //
299   // Due to potential for out-of-order decode vs presentation time, this method
300   // should only be used to determine adjacency of non-keyframes with the end of
301   // |buffers_|, when determining if a non-keyframe with |decode_timestamp|
302   // continues the decode sequence of the coded frame group at the end of
303   // |buffers_|.
304   bool IsNextInDecodeSequence(DecodeTimestamp decode_timestamp) const;
305
306   // Helper method for Appending |range| to the end of this range.  If |range|'s
307   // first buffer time is before the time of the last buffer in this range,
308   // returns kNoTimestamp.  Otherwise, returns the closest time within
309   // [|range|'s start time, |range|'s first buffer time] that is at or after the
310   // this range's GetEndTimestamp(). This allows |range| to potentially be
311   // determined to be adjacent within fudge room for appending to the end of
312   // this range, especially if |range| has a start time that is before its first
313   // buffer's time.
314   base::TimeDelta NextRangeStartTimeForAppendRangeToEnd(
315       const SourceBufferRange& range) const;
316
317   // Returns an index (or iterator) into |buffers_| pointing to the first buffer
318   // at or after |timestamp|.  If |skip_given_timestamp| is true, this returns
319   // the first buffer with timestamp strictly greater than |timestamp|. If
320   // |buffers_| has no such buffer, returns |buffers_.size()| (or
321   // |buffers_.end()|).
322   size_t GetBufferIndexAt(base::TimeDelta timestamp,
323                           bool skip_given_timestamp) const;
324   BufferQueue::const_iterator GetBufferItrAt(base::TimeDelta timestamp,
325                                              bool skip_given_timestamp) const;
326
327   // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
328   // |timestamp|. If |skip_given_timestamp| is true, this returns the first
329   // keyframe with a timestamp strictly greater than |timestamp|.
330   KeyframeMap::const_iterator GetFirstKeyframeAt(
331       base::TimeDelta timestamp,
332       bool skip_given_timestamp) const;
333
334   // Returns an iterator in |keyframe_map_| pointing to the first keyframe
335   // before or at |timestamp|.
336   KeyframeMap::const_iterator GetFirstKeyframeAtOrBefore(
337       base::TimeDelta timestamp) const;
338
339   // Helper method to delete buffers in |buffers_| starting at
340   // |starting_point|, an index in |buffers_|.
341   // Returns true if everything in the range was removed. Returns
342   // false if the range still contains buffers.
343   bool TruncateAt(const size_t starting_point, BufferQueue* deleted_buffers);
344
345   // Updates |highest_frame_| to be the frame with highest PTS in the last GOP
346   // in this range.  If there are no buffers in this range, resets
347   // |highest_frame_|.
348   // Normally, incremental additions to this range should just use
349   // UpdateEndTime(). When removing buffers from this range (which could be out
350   // of order presentation vs decode order), inspecting the last buffer in
351   // decode order of this range can be insufficient to determine the correct
352   // presentation end time of this range. Hence this helper method.
353   void UpdateEndTimeUsingLastGOP();
354
355   // Helper for debugging state.
356   std::string ToStringForDebugging() const;
357
358   // Keeps track of whether gaps are allowed.
359   const GapPolicy gap_policy_;
360
361   // The ordered list of buffers in this range.
362   BufferQueue buffers_;
363
364   // Index into |buffers_| for the next buffer to be returned by
365   // GetNextBuffer(), set to -1 by ResetNextBufferPosition().
366   int next_buffer_index_;
367
368   // Caches the buffer, if any, with the highest PTS currently in |buffers_|.
369   // This is nullptr if this range is empty.  This is useful in determining
370   // range membership and adjacency.
371   scoped_refptr<StreamParserBuffer> highest_frame_;
372
373   // Called to get the largest interbuffer distance seen so far in the stream.
374   InterbufferDistanceCB interbuffer_distance_cb_;
375
376   // Stores the amount of memory taken up by the data in |buffers_|.
377   size_t size_in_bytes_;
378
379   // If the first buffer in this range is the beginning of a coded frame group,
380   // |range_start_pts_| is the presentation time when the coded frame group
381   // begins. This is especially important in muxed media where the first coded
382   // frames for each track do not necessarily begin at the same time.
383   // |range_start_pts_| may be <= the timestamp of the first buffer in
384   // |buffers_|. |range_start_pts_| is kNoTimestamp if this range does not start
385   // at the beginning of a coded frame group, which can happen by range removal
386   // or split when we don't have a way of knowing, across potentially multiple
387   // muxed streams, the coded frame group start timestamp for the new range.
388   base::TimeDelta range_start_pts_;
389
390   // Index base of all positions in |keyframe_map_|. In other words, the
391   // real position of entry |k| of |keyframe_map_| in the range is:
392   //   keyframe_map_[k] - keyframe_map_index_base_
393   int keyframe_map_index_base_;
394
395   // Maps keyframe presentation timestamps to GOP start index of |buffers_|
396   // (with index adjusted by |keyframe_map_index_base_|);
397   KeyframeMap keyframe_map_;
398 };
399
400 }  // namespace media
401
402 #endif  // MEDIA_FILTERS_SOURCE_BUFFER_RANGE_H_