Index: media/filters/chunk_demuxer.h |
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..fc529a32a94f3dca7c522a9a416b728d05fdc562 |
--- /dev/null |
+++ b/media/filters/chunk_demuxer.h |
@@ -0,0 +1,190 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Implements a Demuxer that can switch among different data sources mid-stream. |
+// Uses FFmpegDemuxer under the covers, so see the caveats at the top of |
+// ffmpeg_demuxer.h. |
+ |
+#ifndef MEDIA_FILTERS_CHUNK_DEMUXER_H_ |
+#define MEDIA_FILTERS_CHUNK_DEMUXER_H_ |
+ |
+#include <list> |
+ |
+#include "base/synchronization/lock.h" |
+#include "media/base/filter_factories.h" |
+#include "media/base/filters.h" |
+#include "media/webm/webm_parser.h" |
+ |
+struct AVFormatContext; |
+ |
+namespace media { |
+ |
+class ChunkDemuxer; |
+class ChunkDemuxerStream; |
+ |
+// Class used by an external object to send media data to the |
+// Demuxer. This object is created by the DemuxerFactory and |
+// contains the Demuxer that will be returned in the next Build() |
+// call on the factory. The external object tells the factory |
+// to create one of these objects before it starts the Pipeline. |
+// It does this because the external object may need to make AddData() |
+// calls before the pipeline has completely initialized. This class |
+// allows data from these calls to be queued until initialization |
+// completes. It represents the minimal operations needed by |
+// the external object to talk to the Demuxer. It also allows |
+// the external object to have a longer lifetime than the pipeline. |
+class MediaDataSink { |
+ public: |
+ MediaDataSink(const scoped_refptr<ChunkDemuxer>& demuxer); |
+ ~MediaDataSink(); |
+ |
+ // Flush all data passed via AddData(). |
+ void Flush(); |
+ |
+ // Sends media data to the demuxer. Returns true if the data is valid. |
+ bool AddData(const uint8* data, unsigned length); |
+ |
+ // Signals that playback is shutting down and further AddData() calls |
+ // should fail. This also cancels pending Read()s on DemuxerStreams. |
+ void Shutdown(); |
+ |
+ private: |
+ scoped_refptr<ChunkDemuxer> demuxer_; |
+}; |
scherkus (not reviewing)
2011/06/23 18:50:18
DISALLOW etc
acolwell GONE FROM CHROMIUM
2011/06/23 22:42:17
Done.
|
+ |
+class ChunkDemuxer : public Demuxer { |
+ public: |
+ ChunkDemuxer(); |
+ virtual ~ChunkDemuxer(); |
+ |
+ bool Init(const uint8* data, int size); |
+ |
+ // Filter implementation. |
+ virtual void set_host(FilterHost* filter_host); |
+ virtual void Stop(FilterCallback* callback); |
+ virtual void Seek(base::TimeDelta time, const FilterStatusCB& cb); |
+ virtual void OnAudioRendererDisabled(); |
+ virtual void SetPreload(Preload preload); |
+ |
+ // Demuxer implementation. |
+ virtual scoped_refptr<DemuxerStream> GetStream(DemuxerStream::Type type); |
+ virtual base::TimeDelta GetStartTime() const; |
+ |
+ // Methods used by MediaDataSink |
+ void FlushData(); |
+ bool AddData(const uint8* data, unsigned length); |
+ void Shutdown(); |
+ |
+ private: |
+ // Helper class that collects information from the INFO & TRACKS elements |
+ // passed to Init(). |
+ class InfoTrackWebMParserClient : public WebMParserClient { |
scherkus (not reviewing)
2011/06/23 18:50:18
any reason why we can't break this out into media/
acolwell GONE FROM CHROMIUM
2011/06/23 22:42:17
This implementation is specific to this demuxer. F
|
+ public: |
+ InfoTrackWebMParserClient(); |
+ |
+ int64 timecode_scale() const; |
+ double duration() const; |
+ int64 audio_track_num() const; |
+ int64 audio_default_duration() const; |
+ int64 video_track_num() const; |
+ int64 video_default_duration() const; |
scherkus (not reviewing)
2011/06/23 18:50:18
none of these durations mention the units
why not
acolwell GONE FROM CHROMIUM
2011/06/23 22:42:17
Done.
|
+ |
+ // WebMParserClient methods |
+ virtual bool OnListStart(int id); |
+ virtual bool OnListEnd(int id); |
+ virtual bool OnUInt(int id, int64 val); |
+ virtual bool OnFloat(int id, double val); |
+ virtual bool OnBinary(int id, const uint8* data, int size); |
+ virtual bool OnString(int id, const std::string& str); |
+ virtual bool OnSimpleBlock(int track_num, int timecode, |
+ int flags, |
+ const uint8* data, int size); |
+ private: |
+ int64 timecode_scale_; |
+ double duration_; |
+ int64 track_type_; |
+ int64 track_num_; |
+ int64 track_default_duration_; |
+ int64 audio_track_num_; |
+ int64 audio_default_duration_; |
+ int64 video_track_num_; |
+ int64 video_default_duration_; |
+ }; |
+ |
+ enum State { |
+ WAITING_FOR_INIT, |
+ INITIALIZED, |
+ INIT_ERROR, |
+ SHUTDOWN, |
+ }; |
+ |
+ void ChangeState(State new_state); |
+ |
+ // Generates an AVFormatContext for the INFO & TRACKS elements contained |
+ // in |data|. Returns NULL if parsing |data| fails. |
+ AVFormatContext* CreateFormatContext(const uint8* data, int size) const; |
+ |
+ // Sets up |audio_| & |video_| DemuxerStreams based on the data in |
+ // |format_context_|. Returns false if no valid audio or video stream were |
+ // found. |
+ bool SetupStreams(); |
+ |
+ // Parse all the buffers in |pending_buffers_|. Returns false if parsing one |
+ // of the buffers fails. |
+ bool ParsePendingBuffers(); |
+ |
+ // Parse a buffer that was passed to AddData(). |data| is expected to contain |
+ // one or more WebM Clusters. Returns false if parsing the data fails. |
+ bool ParseAndAddData_Locked(const uint8* data, int length); |
+ |
+ base::Lock lock_; |
+ State state_; |
+ |
+ base::TimeDelta seek_time_; |
+ FilterStatusCB seek_cb_; |
+ |
+ scoped_refptr<ChunkDemuxerStream> audio_; |
+ scoped_refptr<ChunkDemuxerStream> video_; |
+ |
+ AVFormatContext* format_context_; |
+ |
+ int64 buffered_bytes_; |
+ |
+ bool first_seek_; |
+ base::TimeDelta duration_; |
+ |
+ InfoTrackWebMParserClient info_; |
+ |
+ typedef std::list<scoped_refptr<media::Buffer> > BufferList; |
+ BufferList pending_buffers_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ChunkDemuxer); |
+}; |
+ |
+class ChunkDemuxerFactory : public DemuxerFactory { |
+ public: |
+ // Takes a reference to |demuxer_factory|. |
+ ChunkDemuxerFactory(DataSourceFactory* data_source_factory); |
+ virtual ~ChunkDemuxerFactory(); |
+ |
+ bool IsUrlSupported(const std::string& url) const; |
+ MediaDataSink* CreateMediaDataSink(); |
+ |
+ // DemuxerFactory methods. |
+ virtual void Build(const std::string& url, BuildCallback* cb); |
+ virtual DemuxerFactory* Clone() const; |
+ |
+ private: |
+ static const char kURLPrefix[]; |
+ class BuildState; |
+ |
+ scoped_ptr<DataSourceFactory> data_source_factory_; |
+ scoped_refptr<ChunkDemuxer> demuxer_; |
+ |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerFactory); |
+}; |
+ |
+} // namespace media |
+ |
+#endif // MEDIA_FILTERS_CHUNK_DEMUXER_H_ |