cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / media / filters / chunk_demuxer.h
blobe7f6caed37c9c4ab0eab72d3329b35688b38f907
1 // Copyright (c) 2012 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.
5 #ifndef MEDIA_FILTERS_CHUNK_DEMUXER_H_
6 #define MEDIA_FILTERS_CHUNK_DEMUXER_H_
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
13 #include "base/synchronization/lock.h"
14 #include "media/base/byte_queue.h"
15 #include "media/base/demuxer.h"
16 #include "media/base/ranges.h"
17 #include "media/base/stream_parser.h"
18 #include "media/base/text_track.h"
19 #include "media/filters/source_buffer_stream.h"
21 namespace media {
23 class ChunkDemuxerStream;
24 class FFmpegURLProtocol;
25 class SourceState;
27 // Demuxer implementation that allows chunks of media data to be passed
28 // from JavaScript to the media stack.
29 class MEDIA_EXPORT ChunkDemuxer : public Demuxer {
30 public:
31 enum Status {
32 kOk, // ID added w/o error.
33 kNotSupported, // Type specified is not supported.
34 kReachedIdLimit, // Reached ID limit. We can't handle any more IDs.
37 // |open_cb| Run when Initialize() is called to signal that the demuxer
38 // is ready to receive media data via AppenData().
39 // |need_key_cb| Run when the demuxer determines that an encryption key is
40 // needed to decrypt the content.
41 // |add_text_track_cb| Run when demuxer detects the presence of an inband
42 // text track.
43 // |log_cb| Run when parsing error messages need to be logged to the error
44 // console.
45 ChunkDemuxer(const base::Closure& open_cb,
46 const NeedKeyCB& need_key_cb,
47 const AddTextTrackCB& add_text_track_cb,
48 const LogCB& log_cb);
49 virtual ~ChunkDemuxer();
51 // Demuxer implementation.
52 virtual void Initialize(DemuxerHost* host,
53 const PipelineStatusCB& cb) OVERRIDE;
54 virtual void Stop(const base::Closure& callback) OVERRIDE;
55 virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
56 virtual void OnAudioRendererDisabled() OVERRIDE;
57 virtual DemuxerStream* GetStream(DemuxerStream::Type type) OVERRIDE;
58 virtual base::TimeDelta GetStartTime() const OVERRIDE;
60 // Methods used by an external object to control this demuxer.
62 // Indicates that a new Seek() call is on its way. Any pending Reads on the
63 // DemuxerStream objects should be aborted immediately inside this call and
64 // future Read calls should return kAborted until the Seek() call occurs.
65 // This method MUST ALWAYS be called before Seek() is called to signal that
66 // the next Seek() call represents the seek point we actually want to return
67 // data for.
68 // |seek_time| - The presentation timestamp for the seek that triggered this
69 // call. It represents the most recent position the caller is trying to seek
70 // to.
71 void StartWaitingForSeek(base::TimeDelta seek_time);
73 // Indicates that a Seek() call is on its way, but another seek has been
74 // requested that will override the impending Seek() call. Any pending Reads
75 // on the DemuxerStream objects should be aborted immediately inside this call
76 // and future Read calls should return kAborted until the next
77 // StartWaitingForSeek() call. This method also arranges for the next Seek()
78 // call received before a StartWaitingForSeek() call to immediately call its
79 // callback without waiting for any data.
80 // |seek_time| - The presentation timestamp for the seek request that
81 // triggered this call. It represents the most recent position the caller is
82 // trying to seek to.
83 void CancelPendingSeek(base::TimeDelta seek_time);
85 // Registers a new |id| to use for AppendData() calls. |type| indicates
86 // the MIME type for the data that we intend to append for this ID.
87 // kOk is returned if the demuxer has enough resources to support another ID
88 // and supports the format indicated by |type|.
89 // kNotSupported is returned if |type| is not a supported format.
90 // kReachedIdLimit is returned if the demuxer cannot handle another ID right
91 // now.
92 Status AddId(const std::string& id, const std::string& type,
93 std::vector<std::string>& codecs);
95 // Removed an ID & associated resources that were previously added with
96 // AddId().
97 void RemoveId(const std::string& id);
99 // Gets the currently buffered ranges for the specified ID.
100 Ranges<base::TimeDelta> GetBufferedRanges(const std::string& id) const;
102 // Appends media data to the source buffer associated with |id|.
103 void AppendData(const std::string& id, const uint8* data, size_t length);
105 // Aborts parsing the current segment and reset the parser to a state where
106 // it can accept a new segment.
107 void Abort(const std::string& id);
109 // Remove buffers between |start| and |end| for the source buffer
110 // associated with |id|.
111 void Remove(const std::string& id, base::TimeDelta start,
112 base::TimeDelta end);
114 // Returns the current presentation duration.
115 double GetDuration();
116 double GetDuration_Locked();
118 // Notifies the demuxer that the duration of the media has changed to
119 // |duration|.
120 void SetDuration(double duration);
122 // Sets a time |offset| to be applied to subsequent buffers appended to the
123 // source buffer associated with |id|. Returns true if the offset is set
124 // properly, false if the offset cannot be applied because we're in the
125 // middle of parsing a media segment.
126 bool SetTimestampOffset(const std::string& id, base::TimeDelta offset);
128 // Called to signal changes in the "end of stream"
129 // state. UnmarkEndOfStream() must not be called if a matching
130 // MarkEndOfStream() has not come before it.
131 void MarkEndOfStream(PipelineStatus status);
132 void UnmarkEndOfStream();
134 // Set the append window start and end values for the source buffer
135 // associated with |id|.
136 void SetAppendWindowStart(const std::string& id, base::TimeDelta start);
137 void SetAppendWindowEnd(const std::string& id, base::TimeDelta end);
139 void Shutdown();
141 void SetMemoryLimitsForTesting(int memory_limit);
143 private:
144 enum State {
145 WAITING_FOR_INIT,
146 INITIALIZING,
147 INITIALIZED,
148 ENDED,
149 PARSE_ERROR,
150 SHUTDOWN,
153 void ChangeState_Locked(State new_state);
155 // Reports an error and puts the demuxer in a state where it won't accept more
156 // data.
157 void ReportError_Locked(PipelineStatus error);
159 // Returns true if any stream has seeked to a time without buffered data.
160 bool IsSeekWaitingForData_Locked() const;
162 // Returns true if all streams can successfully call EndOfStream,
163 // false if any can not.
164 bool CanEndOfStream_Locked() const;
166 // SourceState callbacks.
167 void OnSourceInitDone(bool success, base::TimeDelta duration);
169 // Creates a DemuxerStream for the specified |type|.
170 // Returns a new ChunkDemuxerStream instance if a stream of this type
171 // has not been created before. Returns NULL otherwise.
172 ChunkDemuxerStream* CreateDemuxerStream(DemuxerStream::Type type);
174 bool OnTextBuffers(TextTrack* text_track,
175 const StreamParser::BufferQueue& buffers);
176 void OnNewMediaSegment(const std::string& source_id,
177 base::TimeDelta start_timestamp);
179 // Computes the intersection between the video & audio
180 // buffered ranges.
181 Ranges<base::TimeDelta> ComputeIntersection() const;
183 // Applies |time_offset| to the timestamps of |buffers|.
184 void AdjustBufferTimestamps(const StreamParser::BufferQueue& buffers,
185 base::TimeDelta timestamp_offset);
187 // Returns true if |source_id| is valid, false otherwise.
188 bool IsValidId(const std::string& source_id) const;
190 // Increases |duration_| if |last_appended_buffer_timestamp| exceeds the
191 // current |duration_|. The |duration_| is set to the end buffered timestamp
192 // of |stream|.
193 void IncreaseDurationIfNecessary(
194 base::TimeDelta last_appended_buffer_timestamp,
195 ChunkDemuxerStream* stream);
197 // Decreases |duration_| if the buffered region is less than |duration_| when
198 // EndOfStream() is called.
199 void DecreaseDurationIfNecessary();
201 // Sets |duration_| to |new_duration|, sets |user_specified_duration_| to -1
202 // and notifies |host_|.
203 void UpdateDuration(base::TimeDelta new_duration);
205 // Returns the ranges representing the buffered data in the demuxer.
206 Ranges<base::TimeDelta> GetBufferedRanges() const;
208 // Start returning data on all DemuxerStreams.
209 void StartReturningData();
211 // Aborts pending reads on all DemuxerStreams.
212 void AbortPendingReads();
214 // Completes any pending reads if it is possible to do so.
215 void CompletePendingReadsIfPossible();
217 // Seeks all SourceBufferStreams to |seek_time|.
218 void SeekAllSources(base::TimeDelta seek_time);
220 mutable base::Lock lock_;
221 State state_;
222 bool cancel_next_seek_;
224 DemuxerHost* host_;
225 base::Closure open_cb_;
226 NeedKeyCB need_key_cb_;
227 AddTextTrackCB add_text_track_cb_;
228 // Callback used to report error strings that can help the web developer
229 // figure out what is wrong with the content.
230 LogCB log_cb_;
232 PipelineStatusCB init_cb_;
233 PipelineStatusCB seek_cb_;
235 scoped_ptr<ChunkDemuxerStream> audio_;
236 scoped_ptr<ChunkDemuxerStream> video_;
238 // Keeps |audio_| alive when audio has been disabled.
239 scoped_ptr<ChunkDemuxerStream> disabled_audio_;
241 base::TimeDelta duration_;
243 // The duration passed to the last SetDuration(). If
244 // SetDuration() is never called or an AppendData() call or
245 // a EndOfStream() call changes |duration_|, then this
246 // variable is set to < 0 to indicate that the |duration_| represents
247 // the actual duration instead of a user specified value.
248 double user_specified_duration_;
250 typedef std::map<std::string, SourceState*> SourceStateMap;
251 SourceStateMap source_state_map_;
253 // Used to ensure that (1) config data matches the type and codec provided in
254 // AddId(), (2) only 1 audio and 1 video sources are added, and (3) ids may be
255 // removed with RemoveID() but can not be re-added (yet).
256 std::string source_id_audio_;
257 std::string source_id_video_;
259 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxer);
262 } // namespace media
264 #endif // MEDIA_FILTERS_CHUNK_DEMUXER_H_