Index: media/filters/adaptive_demuxer.h |
diff --git a/media/filters/adaptive_demuxer.h b/media/filters/adaptive_demuxer.h |
index 6402b039022a997d5b4c31002b3bbe10b5ab0338..77ea1100445eace08693f49f61aae1a74ac30b9b 100644 |
--- a/media/filters/adaptive_demuxer.h |
+++ b/media/filters/adaptive_demuxer.h |
@@ -23,10 +23,29 @@ |
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(). |
Ami GONE FROM CHROMIUM
2011/05/24 06:14:12
Add a pointer to the ascii art below?
acolwell GONE FROM CHROMIUM
2011/05/24 23:45:16
Done.
|
+ // |
+ // 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(PipelineStatus, base::TimeDelta)> 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 +54,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(); |
+ |
// 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 +77,20 @@ 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(PipelineStatus status, |
+ base::TimeDelta seek_time); |
+ |
StreamVector streams_; |
// Guards the members below. Only held for simple variable reads/writes, not |
// during async operation. |
@@ -60,12 +98,37 @@ 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); |
}; |
class AdaptiveDemuxer : public Demuxer { |
public: |
typedef std::vector<scoped_refptr<Demuxer> > DemuxerVector; |
+ typedef std::vector<int> StreamIdVector; |
// |demuxers| must be non-empty, and the index arguments must be valid indexes |
// into |demuxers|, or -1 to indicate no demuxer is serving that type. |
@@ -74,8 +137,14 @@ 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; |
+ |
+ // Get all of the video stream IDs. |
+ StreamIdVector GetVideoIds() const; |
// Filter implementation. |
virtual void Stop(FilterCallback* callback); |
@@ -92,14 +161,72 @@ 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() |
+ // | |
+ // \|/ |
+ // +--------------+ |
+ // | Found Switch | |
+ // | Point in | No (Seeking to get more index data.) |
+ // | Index Data? |---> |demuxers_[stream_index]->Seek()| |
+ // +--------------+ | |
+ // |Yes \|/ |
+ // | OnIndexSeekDone() |
+ // | | |
+ // \|/ \|/ |
+ // (Seeking stream to switch point.) Yes +--------------+ |
+ // |demuxers_[stream_index]->Seek()| <------| Found Switch | |
+ // | | Point in | |
+ // | | Index Data? | |
+ // | +--------------+ |
+ // | | No |
+ // \|/ \|/ |
+ // OnStreamSeekDone() seek_cb(ERROR) |
+ // | |
+ // \|/ |
+ // 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. |
+ void OnStreamSeekDone(base::TimeDelta seek_point, |
+ const AdaptiveDemuxerStream::SeekFunctionCB& seek_cb, |
+ 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); |
}; |