Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Unified Diff: media/filters/adaptive_demuxer.h

Issue 7044008: Initial implementation of stream switching in AdaptiveDemuxer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressing final CR concerns and fixing Lint errors. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/pipeline_status.h ('k') | media/filters/adaptive_demuxer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
};
« no previous file with comments | « media/base/pipeline_status.h ('k') | media/filters/adaptive_demuxer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698