Chromium Code Reviews| 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..b59f471200760d85e614681cba6c0e9b2554ff99 |
| --- /dev/null |
| +++ b/media/filters/chunk_demuxer.h |
| @@ -0,0 +1,189 @@ |
| +// 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/filters/webm_parser.h" |
| + |
| +struct AVFormatContext; |
| + |
| +namespace media { |
| + |
| +class ChunkDemuxer; |
| +class ChunkDemuxerStream; |
| + |
| +// Class used by WebMediaPlayerImpl 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 WebMediaPlayerImpl tells the factory |
| +// to create one of these objects before it starts the Pipeline. |
| +// It does this because WebMediaPlayerImpl may get AddData() |
| +// calls from JavaScript before the pipeline has completely initialized. |
| +// This allows data from these calls to be queued until initialization |
| +// completes. This class represents the minimal operations needed by |
| +// WebMediaPlayerImpl to talk to the Demuxer. |
|
scherkus (not reviewing)
2011/06/22 17:31:09
media doesn't known about WebMediaPlayerImpl
this
acolwell GONE FROM CHROMIUM
2011/06/23 16:51:28
Done.
|
| +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_; |
| +}; |
| + |
| +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 { |
| + 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; |
| + |
| + // 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_ |