| 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..0abf0518bf149ab45fecfe239ab203647c4e2dac
|
| --- /dev/null
|
| +++ b/media/filters/chunk_demuxer.h
|
| @@ -0,0 +1,191 @@
|
| +// 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_;
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(MediaDataSink);
|
| +};
|
| +
|
| +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;
|
| + base::TimeDelta audio_default_duration() const;
|
| + int64 video_track_num() const;
|
| + base::TimeDelta 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_;
|
| + base::TimeDelta audio_default_duration_;
|
| + int64 video_track_num_;
|
| + base::TimeDelta 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_
|
|
|