| Index: media/filters/adaptive_demuxer.h
|
| diff --git a/media/filters/adaptive_demuxer.h b/media/filters/adaptive_demuxer.h
|
| index 6402b039022a997d5b4c31002b3bbe10b5ab0338..8dc3334f21b8e96a3ed21ff739ad379c6a8a4503 100644
|
| --- a/media/filters/adaptive_demuxer.h
|
| +++ b/media/filters/adaptive_demuxer.h
|
| @@ -23,10 +23,31 @@
|
| namespace media {
|
|
|
| class AdaptiveDemuxer;
|
| +class StreamSwitchManager;
|
|
|
| class AdaptiveDemuxerStream : public DemuxerStream {
|
| public:
|
| typedef std::vector<scoped_refptr<DemuxerStream> > StreamVector;
|
| + typedef std::deque<ReadCallback> ReadCBQueue;
|
| +
|
| + // Typedefs used by the stream switching code to seek a stream to a desired
|
| + // location. The AdaptiveDemuxer constructs a SeekFunction for the stream
|
| + // being switched to and passes this function to
|
| + // AdaptiveDemuxerStream::ChangeCurrentStream(). For more information about
|
| + // how the SeekFunction is implemented, look at the comments for
|
| + // AdaptiveDemuxer::StartStreamSwitchSeek() below.
|
| + //
|
| + // Callback for SeekFunction. The PipelineStatus parameter indicates whether
|
| + // the seek was successful or not. The base::TimeDelta parameter indicates the
|
| + // time we actually seeked to. If the seek was successful this should be >=
|
| + // than the requested time.
|
| + typedef base::Callback<void(base::TimeDelta, PipelineStatus)> SeekFunctionCB;
|
| +
|
| + // Wraps a function that performs a seek on a specified stream. The
|
| + // base::TimeDelta parameter indicates what time to seek to. The
|
| + // SeekFunctionCBparameter specifies the callback we want called when the seek
|
| + // completes.
|
| + typedef base::Callback<void(base::TimeDelta, SeekFunctionCB)> SeekFunction;
|
|
|
| // Keeps references to the passed-in streams. |streams| must be non-empty and
|
| // all the streams in it must agree on type and media_format (or be NULL).
|
| @@ -35,9 +56,14 @@ class AdaptiveDemuxerStream : public DemuxerStream {
|
| AdaptiveDemuxerStream(StreamVector const& streams, int initial_stream);
|
| virtual ~AdaptiveDemuxerStream();
|
|
|
| + // Notifies this stream that a Seek() was requested on the demuxer.
|
| + void OnAdaptiveDemuxerSeek(base::TimeDelta seek_time);
|
| +
|
| // Change the stream to satisfy subsequent Read() requests from. The
|
| - // referenced pointer must not be NULL.
|
| - void ChangeCurrentStream(int index);
|
| + // referenced pointer must not be NULL. The SeekFunction parameter
|
| + // provides a way to seek |streams_[index]| to a specific time.
|
| + void ChangeCurrentStream(int index, const SeekFunction& seek_function,
|
| + const PipelineStatusCB& cb);
|
|
|
| // DemuxerStream methods.
|
| virtual void Read(const ReadCallback& read_callback);
|
| @@ -53,6 +79,19 @@ class AdaptiveDemuxerStream : public DemuxerStream {
|
| // DEBUG_MODE-only CHECK that the data members are in a reasonable state.
|
| void DCheckSanity();
|
|
|
| + void OnReadDone(Buffer* buffer);
|
| +
|
| + bool IsSwitchPending_Locked() const;
|
| + bool CanStartSwitch_Locked() const;
|
| +
|
| + // Starts the stream switch. This method expects that no Read()s are
|
| + // outstanding on |streams_[current_stream_index_]|.
|
| + void StartSwitch();
|
| +
|
| + // Called by the SeekFunction when it has completed the seek on
|
| + // |streams_[switch_index_]|.
|
| + void OnSwitchSeekDone(base::TimeDelta seek_time, PipelineStatus status);
|
| +
|
| StreamVector streams_;
|
| // Guards the members below. Only held for simple variable reads/writes, not
|
| // during async operation.
|
| @@ -60,6 +99,30 @@ class AdaptiveDemuxerStream : public DemuxerStream {
|
| int current_stream_index_;
|
| bool bitstream_converter_enabled_;
|
|
|
| + // The number of outstanding Read()'s on |streams_[current_stream_index_]|.
|
| + int pending_reads_;
|
| +
|
| + // A queue of callback objects passed to Read().
|
| + ReadCBQueue read_cb_queue_;
|
| +
|
| + // Callback passed to ChangeCurrentStream(). This is called & reset when the
|
| + // stream switch has completed. Callback object is null when a stream switch
|
| + // is not in progress.
|
| + PipelineStatusCB switch_cb_;
|
| +
|
| + // The index of the stream we are switching to. During a stream switch
|
| + // 0 <= |switch_index_| < |streams_.size()| and
|
| + // |streams_[switch_index]| MUST NOT be null. |switch_index_| is set to -1 if
|
| + // a stream switch is not in progress.
|
| + int switch_index_;
|
| +
|
| + // Function used to seek |streams_[switch_index_]| to a specific time. The
|
| + // callback is null if a switch is not pending.
|
| + SeekFunction switch_seek_function_;
|
| +
|
| + // The timestamp of the last buffer returned via a Read() callback.
|
| + base::TimeDelta last_buffer_timestamp_;
|
| +
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerStream);
|
| };
|
|
|
| @@ -74,8 +137,11 @@ class AdaptiveDemuxer : public Demuxer {
|
| int initial_video_demuxer_index);
|
| virtual ~AdaptiveDemuxer();
|
|
|
| - // Change which demuxers the streams will use.
|
| - void ChangeCurrentDemuxer(int audio_index, int video_index);
|
| + // Change to a different video stream.
|
| + void ChangeVideoStream(int video_id, const PipelineStatusCB& done_cb);
|
| +
|
| + // Get the ID of the current video stream.
|
| + int GetCurrentVideoId() const;
|
|
|
| // Filter implementation.
|
| virtual void Stop(FilterCallback* callback);
|
| @@ -92,14 +158,73 @@ class AdaptiveDemuxer : public Demuxer {
|
| // Returns a pointer to the currently active demuxer of the given type.
|
| Demuxer* current_demuxer(DemuxerStream::Type type);
|
|
|
| + // Called when the AdaptiveDemuxerStream completes a stream switch.
|
| + void ChangeVideoStreamDone(int new_stream_index,
|
| + const PipelineStatusCB& done_cb,
|
| + PipelineStatus status);
|
| +
|
| + // Methods for SeekFunction.
|
| + //
|
| + // Seeking on a stream follows the flow below.
|
| + //
|
| + // SeekFunction.Run() -> StartStreamSwitchSeek()
|
| + // |
|
| + // V
|
| + // +--------------+
|
| + // | Found Switch |
|
| + // | Point in | No (Seeking to get more index data.)
|
| + // | Index Data? |---> |demuxers_[stream_index]->Seek()|
|
| + // +--------------+ |
|
| + // |Yes V
|
| + // | OnIndexSeekDone()
|
| + // | |
|
| + // V V
|
| + // (Seeking stream to switch point.) Yes +--------------+
|
| + // |demuxers_[stream_index]->Seek()| <------| Found Switch |
|
| + // | | Point in |
|
| + // | | Index Data? |
|
| + // | +--------------+
|
| + // | | No
|
| + // V V
|
| + // OnStreamSeekDone() seek_cb(ERROR)
|
| + // |
|
| + // V
|
| + // seek_cb(OK | ERROR)
|
| + //
|
| + // When AdaptiveDemuxer creates a SeekFunction object it points to this
|
| + // method.
|
| + void StartStreamSwitchSeek(
|
| + DemuxerStream::Type type,
|
| + int stream_index,
|
| + base::TimeDelta seek_time,
|
| + const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb);
|
| +
|
| + // Called when the seek for index data initiated by StartStreamSwitchSeek()
|
| + // completes.
|
| + void OnIndexSeekDone(DemuxerStream::Type type,
|
| + int stream_index,
|
| + base::TimeDelta seek_time,
|
| + const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb,
|
| + PipelineStatus status);
|
| +
|
| + // Called when the stream seek initiated by StartStreamSwitchSeek() or
|
| + // OnIndexSeekDone() completes.
|
| + static void OnStreamSeekDone(
|
| + const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb,
|
| + base::TimeDelta seek_point,
|
| + PipelineStatus status);
|
| +
|
| DemuxerVector demuxers_;
|
| scoped_refptr<AdaptiveDemuxerStream> audio_stream_;
|
| scoped_refptr<AdaptiveDemuxerStream> video_stream_;
|
| // Guards the members below. Only held for simple variable reads/writes, not
|
| // during async operation.
|
| - base::Lock lock_;
|
| + mutable base::Lock lock_;
|
| int current_audio_demuxer_index_;
|
| int current_video_demuxer_index_;
|
| + float playback_rate_;
|
| + bool switch_pending_;
|
| + scoped_refptr<StreamSwitchManager> stream_switch_manager_;
|
|
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxer);
|
| };
|
|
|