Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / source_buffer_state.h
1 // Copyright 2016 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_STATE_H_
6 #define MEDIA_FILTERS_SOURCE_BUFFER_STATE_H_
7
8 #include "base/bind.h"
9 #include "base/memory/memory_pressure_listener.h"
10 #include "base/memory/raw_ptr.h"
11 #include "base/time/time.h"
12 #include "media/base/audio_codecs.h"
13 #include "media/base/demuxer.h"
14 #include "media/base/demuxer_stream.h"
15 #include "media/base/media_export.h"
16 #include "media/base/media_log.h"
17 #include "media/base/stream_parser.h"
18 #include "media/base/stream_parser_buffer.h"
19 #include "media/base/video_codecs.h"
20 #include "media/filters/source_buffer_parse_warnings.h"
21
22 namespace media {
23
24
25 class ChunkDemuxerStream;
26 class FrameProcessor;
27
28 // Contains state belonging to a source id.
29 class MEDIA_EXPORT SourceBufferState {
30  public:
31   // Callback signature used to create ChunkDemuxerStreams.
32   using CreateDemuxerStreamCB =
33       base::RepeatingCallback<ChunkDemuxerStream*(DemuxerStream::Type)>;
34
35   using NewTextTrackCB = base::RepeatingCallback<void(ChunkDemuxerStream*,
36                                                       const TextTrackConfig&)>;
37
38   SourceBufferState(std::unique_ptr<StreamParser> stream_parser,
39                     std::unique_ptr<FrameProcessor> frame_processor,
40                     CreateDemuxerStreamCB create_demuxer_stream_cb,
41                     MediaLog* media_log);
42
43   SourceBufferState(const SourceBufferState&) = delete;
44   SourceBufferState& operator=(const SourceBufferState&) = delete;
45
46   ~SourceBufferState();
47
48   void Init(StreamParser::InitCB init_cb,
49             const std::string& expected_codecs,
50             const StreamParser::EncryptedMediaInitDataCB&
51                 encrypted_media_init_data_cb,
52             NewTextTrackCB new_text_track_cb);
53
54   // Reconfigures this source buffer to use |new_stream_parser|. Caller must
55   // first ensure that ResetParserState() was done to flush any pending frames
56   // from the old stream parser.
57   void ChangeType(std::unique_ptr<StreamParser> new_stream_parser,
58                   const std::string& new_expected_codecs);
59
60   // Appends new data to the StreamParser.
61   // Returns true if the data was successfully appended. Returns false if an
62   // error occurred. |*timestamp_offset| is used and possibly updated by the
63   // append. |append_window_start| and |append_window_end| correspond to the MSE
64   // spec's similarly named source buffer attributes that are used in coded
65   // frame processing.
66   // AppendChunks appends the provided BufferQueue.
67   bool Append(const uint8_t* data,
68               size_t length,
69               base::TimeDelta append_window_start,
70               base::TimeDelta append_window_end,
71               base::TimeDelta* timestamp_offset);
72   bool AppendChunks(std::unique_ptr<StreamParser::BufferQueue> buffer_queue,
73                     base::TimeDelta append_window_start,
74                     base::TimeDelta append_window_end,
75                     base::TimeDelta* timestamp_offset);
76
77   // Aborts the current append sequence and resets the parser.
78   void ResetParserState(base::TimeDelta append_window_start,
79                         base::TimeDelta append_window_end,
80                         base::TimeDelta* timestamp_offset);
81
82   // Calls Remove(|start|, |end|, |duration|) on all
83   // ChunkDemuxerStreams managed by this object.
84   void Remove(base::TimeDelta start,
85               base::TimeDelta end,
86               base::TimeDelta duration);
87
88   // If the buffer is full, attempts to try to free up space, as specified in
89   // the "Coded Frame Eviction Algorithm" in the Media Source Extensions Spec.
90   // Returns false iff buffer is still full after running eviction.
91   // https://w3c.github.io/media-source/#sourcebuffer-coded-frame-eviction
92   bool EvictCodedFrames(base::TimeDelta media_time, size_t newDataSize);
93
94   // Gets invoked when the system is experiencing memory pressure, i.e. there's
95   // not enough free memory. The |media_time| is the media playback position at
96   // the time of memory pressure notification (needed for accurate GC). The
97   // |memory_pressure_level| indicates memory pressure severity. The
98   // |force_instant_gc| is used to force the MSE garbage collection algorithm to
99   // be run right away, without waiting for the next append.
100   void OnMemoryPressure(
101       base::TimeDelta media_time,
102       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
103       bool force_instant_gc);
104
105   // Returns true if currently parsing a media segment, or false otherwise.
106   bool parsing_media_segment() const { return parsing_media_segment_; }
107
108   // Returns the 'Generate Timestamps Flag' for this SourceBuffer's byte stream
109   // format parser as described in the MSE Byte Stream Format Registry.
110   bool generate_timestamps_flag() const {
111     return stream_parser_->GetGenerateTimestampsFlag();
112   }
113
114   // Sets |frame_processor_|'s sequence mode to |sequence_mode|.
115   void SetSequenceMode(bool sequence_mode);
116
117   // Signals the coded frame processor to update its group start timestamp to be
118   // |timestamp_offset| if it is in sequence append mode.
119   void SetGroupStartTimestampIfInSequenceMode(base::TimeDelta timestamp_offset);
120
121   // Returns the range of buffered data in this source, capped at |duration|.
122   // |ended| - Set to true if end of stream has been signaled and the special
123   // end of stream range logic needs to be executed.
124   Ranges<base::TimeDelta> GetBufferedRanges(base::TimeDelta duration,
125                                             bool ended) const;
126
127   // Returns the highest PTS of currently buffered frames in this source, or
128   // base::TimeDelta() if none of the streams contain buffered data.
129   base::TimeDelta GetHighestPresentationTimestamp() const;
130
131   // Returns the highest buffered duration across all streams managed
132   // by this object.
133   // Returns base::TimeDelta() if none of the streams contain buffered data.
134   base::TimeDelta GetMaxBufferedDuration() const;
135
136   // Helper methods that call methods with similar names on all the
137   // ChunkDemuxerStreams managed by this object.
138   void StartReturningData();
139   void AbortReads();
140   void Seek(base::TimeDelta seek_time);
141   void CompletePendingReadIfPossible();
142   void OnSetDuration(base::TimeDelta duration);
143   void MarkEndOfStream();
144   void UnmarkEndOfStream();
145   void Shutdown();
146   // Sets the memory limit on each stream of a specific type.
147   // |memory_limit| is the maximum number of bytes each stream of type |type|
148   // is allowed to hold in its buffer.
149   void SetMemoryLimits(DemuxerStream::Type type, size_t memory_limit);
150   bool IsSeekWaitingForData() const;
151
152   using RangesList = std::vector<Ranges<base::TimeDelta>>;
153   static Ranges<base::TimeDelta> ComputeRangesIntersection(
154       const RangesList& active_ranges,
155       bool ended);
156
157   void SetTracksWatcher(Demuxer::MediaTracksUpdatedCB tracks_updated_cb);
158
159   void SetParseWarningCallback(SourceBufferParseWarningCB parse_warning_cb);
160
161  private:
162   // State advances through this list to PARSER_INITIALIZED.
163   // The intent is to ensure at least one config is received prior to parser
164   // calling initialization callback, and that such initialization callback
165   // occurs at most once per parser.
166   // PENDING_PARSER_RECONFIG occurs if State had reached PARSER_INITIALIZED
167   // before changing to a new StreamParser in ChangeType(). In such case, State
168   // would then advance to PENDING_PARSER_REINIT, then PARSER_INITIALIZED upon
169   // the next initialization segment parsed, but would not run the
170   // initialization callback in this case (since such would already have
171   // occurred on the initial transition from PENDING_PARSER_INIT to
172   // PARSER_INITIALIZED.)
173   enum State {
174     UNINITIALIZED = 0,
175     PENDING_PARSER_CONFIG,
176     PENDING_PARSER_INIT,
177     PARSER_INITIALIZED,
178     PENDING_PARSER_RECONFIG,
179     PENDING_PARSER_REINIT
180   };
181
182   // Initializes |stream_parser_|. Also, updates |expected_audio_codecs| and
183   // |expected_video_codecs|.
184   void InitializeParser(const std::string& expected_codecs);
185
186   // Called by the |stream_parser_| when a new initialization segment is
187   // encountered.
188   // Returns true on a successful call. Returns false if an error occurred while
189   // processing decoder configurations.
190   bool OnNewConfigs(std::string expected_codecs,
191                     std::unique_ptr<MediaTracks> tracks,
192                     const StreamParser::TextTrackConfigMap& text_configs);
193
194   // Called by the |stream_parser_| at the beginning of a new media segment.
195   void OnNewMediaSegment();
196
197   // Called by the |stream_parser_| at the end of a media segment.
198   void OnEndOfMediaSegment();
199
200   // Called by the |stream_parser_| when new buffers have been parsed.
201   // It processes the new buffers using |frame_processor_|, which includes
202   // appending the processed frames to associated demuxer streams for each
203   // frame's track.
204   // Returns true on a successful call. Returns false if an error occurred while
205   // processing the buffers.
206   bool OnNewBuffers(const StreamParser::BufferQueueMap& buffer_queue_map);
207
208   // Called when StreamParser encounters encrypted media init data.
209   void OnEncryptedMediaInitData(EmeInitDataType type,
210                                 const std::vector<uint8_t>& init_data);
211
212   void OnSourceInitDone(const StreamParser::InitParameters& params);
213
214   // Sets memory limits for all demuxer streams.
215   void SetStreamMemoryLimits();
216
217   // Tracks the number of MEDIA_LOGs emitted for segments missing expected audio
218   // or video blocks. Useful to prevent log spam.
219   int num_missing_track_logs_ = 0;
220
221   // During Append(), if OnNewBuffers() coded frame processing updates the
222   // timestamp offset then |*timestamp_offset_during_append_| is also updated
223   // so Append()'s caller can know the new offset. This pointer is only non-NULL
224   // during the lifetime of an Append() call.
225   raw_ptr<base::TimeDelta> timestamp_offset_during_append_;
226
227   // During Append(), coded frame processing triggered by OnNewBuffers()
228   // requires these two attributes. These are only valid during the lifetime of
229   // an Append() call.
230   base::TimeDelta append_window_start_during_append_;
231   base::TimeDelta append_window_end_during_append_;
232
233   // Keeps track of whether a media segment is being parsed.
234   bool parsing_media_segment_;
235
236   // Valid only while |parsing_media_segment_| is true. These flags enable
237   // warning when the parsed media segment doesn't have frames for some track.
238   std::map<StreamParser::TrackId, bool> media_segment_has_data_for_track_;
239
240   // The object used to parse appended data.
241   std::unique_ptr<StreamParser> stream_parser_;
242
243   // Note that ChunkDemuxerStreams are created and owned by the parent
244   // ChunkDemuxer. They are not owned by |this|.
245   using DemuxerStreamMap = std::map<StreamParser::TrackId, ChunkDemuxerStream*>;
246   DemuxerStreamMap audio_streams_;
247   DemuxerStreamMap video_streams_;
248   DemuxerStreamMap text_streams_;
249
250   std::unique_ptr<FrameProcessor> frame_processor_;
251   const CreateDemuxerStreamCB create_demuxer_stream_cb_;
252   raw_ptr<MediaLog> media_log_;
253
254   StreamParser::InitCB init_cb_;
255   StreamParser::EncryptedMediaInitDataCB encrypted_media_init_data_cb_;
256   NewTextTrackCB new_text_track_cb_;
257
258   State state_;
259
260   // During Append(), OnNewConfigs() will trigger the initialization segment
261   // received algorithm. Note, the MSE spec explicitly disallows this algorithm
262   // during an Abort(), since Abort() is allowed only to emit coded frames, and
263   // only if the parser is PARSING_MEDIA_SEGMENT (not an INIT segment). So we
264   // also have a flag here that indicates if Append is in progress and we can
265   // invoke this callback.
266   Demuxer::MediaTracksUpdatedCB init_segment_received_cb_;
267   bool append_in_progress_ = false;
268   bool first_init_segment_received_ = false;
269   bool encrypted_media_init_data_reported_ = false;
270
271   std::vector<AudioCodec> expected_audio_codecs_;
272   std::vector<VideoCodec> expected_video_codecs_;
273 };
274
275 }  // namespace media
276
277 #endif  // MEDIA_FILTERS_SOURCE_BUFFER_STATE_H_