Home | History | Annotate | Download | only in filters
      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