source_buffer_range.h 19 KB

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