Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Implements a Demuxer that can switch among different data sources mid-stream. | 5 // Implements a Demuxer that can switch among different data sources mid-stream. |
| 6 // Uses FFmpegDemuxer under the covers, so see the caveats at the top of | 6 // Uses FFmpegDemuxer under the covers, so see the caveats at the top of |
| 7 // ffmpeg_demuxer.h. | 7 // ffmpeg_demuxer.h. |
| 8 | 8 |
| 9 #ifndef MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ | 9 #ifndef MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ |
| 10 #define MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ | 10 #define MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ |
| 11 | 11 |
| 12 #include <deque> | 12 #include <deque> |
| 13 #include <vector> | 13 #include <vector> |
| 14 | 14 |
| 15 #include "base/callback.h" | 15 #include "base/callback.h" |
| 16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "media/base/buffers.h" | 17 #include "media/base/buffers.h" |
| 18 #include "media/base/filter_factories.h" | 18 #include "media/base/filter_factories.h" |
| 19 #include "media/base/filters.h" | 19 #include "media/base/filters.h" |
| 20 #include "media/base/pipeline.h" | 20 #include "media/base/pipeline.h" |
| 21 #include "media/base/media_format.h" | 21 #include "media/base/media_format.h" |
| 22 | 22 |
| 23 namespace media { | 23 namespace media { |
| 24 | 24 |
| 25 class AdaptiveDemuxer; | 25 class AdaptiveDemuxer; |
| 26 class StreamSwitchManager; | |
| 27 | |
| 28 typedef base::Callback<void(PipelineStatus, base::TimeDelta)> SeekHelperCB; | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
Any reason these need to be outside in namespace s
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
Doco these typedefs.
Their naming is leaving me sc
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 29 typedef base::Callback<void(const base::TimeDelta&, SeekHelperCB)> SeekHelper; | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
TimeDelta is an int64; no need to pass by const&.
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 26 | 30 |
| 27 class AdaptiveDemuxerStream : public DemuxerStream { | 31 class AdaptiveDemuxerStream : public DemuxerStream { |
| 28 public: | 32 public: |
| 29 typedef std::vector<scoped_refptr<DemuxerStream> > StreamVector; | 33 typedef std::vector<scoped_refptr<DemuxerStream> > StreamVector; |
| 34 typedef std::deque<ReadCallback> ReadCBQueue; | |
| 30 | 35 |
| 31 // Keeps references to the passed-in streams. |streams| must be non-empty and | 36 // Keeps references to the passed-in streams. |streams| must be non-empty and |
| 32 // all the streams in it must agree on type and media_format (or be NULL). | 37 // all the streams in it must agree on type and media_format (or be NULL). |
| 33 // |initial_stream| must be a valid index into |streams| and specifies the | 38 // |initial_stream| must be a valid index into |streams| and specifies the |
| 34 // current stream on construction. | 39 // current stream on construction. |
| 35 AdaptiveDemuxerStream(StreamVector const& streams, int initial_stream); | 40 AdaptiveDemuxerStream(StreamVector const& streams, int initial_stream); |
| 36 virtual ~AdaptiveDemuxerStream(); | 41 virtual ~AdaptiveDemuxerStream(); |
| 37 | 42 |
| 43 // Notifies this stream that a Seek() was requested on the demuxer. | |
| 44 void OnAdaptiveDemuxerSeek(); | |
| 45 | |
| 38 // Change the stream to satisfy subsequent Read() requests from. The | 46 // Change the stream to satisfy subsequent Read() requests from. The |
| 39 // referenced pointer must not be NULL. | 47 // referenced pointer must not be NULL. |
| 40 void ChangeCurrentStream(int index); | 48 void ChangeCurrentStream(int index, const SeekHelper& seek_helper, |
| 49 const PipelineStatusCB& cb); | |
| 41 | 50 |
| 42 // DemuxerStream methods. | 51 // DemuxerStream methods. |
| 43 virtual void Read(const ReadCallback& read_callback); | 52 virtual void Read(const ReadCallback& read_callback); |
| 44 virtual Type type(); | 53 virtual Type type(); |
| 45 virtual const MediaFormat& media_format(); | 54 virtual const MediaFormat& media_format(); |
| 46 virtual void EnableBitstreamConverter(); | 55 virtual void EnableBitstreamConverter(); |
| 47 virtual AVStream* GetAVStream(); | 56 virtual AVStream* GetAVStream(); |
| 48 | 57 |
| 49 private: | 58 private: |
| 50 // Returns a pointer to the current stream. | 59 // Returns a pointer to the current stream. |
| 51 DemuxerStream* current_stream(); | 60 DemuxerStream* current_stream(); |
| 52 | 61 |
| 53 // DEBUG_MODE-only CHECK that the data members are in a reasonable state. | 62 // DEBUG_MODE-only CHECK that the data members are in a reasonable state. |
| 54 void DCheckSanity(); | 63 void DCheckSanity(); |
| 55 | 64 |
| 65 void OnReadDone(Buffer* buffer); | |
| 66 | |
| 67 bool IsSwitchPending_Locked() const; | |
| 68 | |
| 69 // Starts the stream switch. This method expects that no Read()s are | |
| 70 // outstanding on | streams_[current_stream_index_] |. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
Inward-facing spaces around |'s are unnecessary (h
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 71 void StartSwitch(); | |
| 72 | |
| 73 // Called by the SeekHelper when it has completed the seek on | |
| 74 // | streams_[switch_index_] |. | |
| 75 void OnSwitchSeekDone(PipelineStatus status, | |
| 76 const base::TimeDelta& seek_time); | |
| 77 | |
| 56 StreamVector streams_; | 78 StreamVector streams_; |
| 57 // Guards the members below. Only held for simple variable reads/writes, not | 79 // Guards the members below. Only held for simple variable reads/writes, not |
| 58 // during async operation. | 80 // during async operation. |
| 59 base::Lock lock_; | 81 base::Lock lock_; |
| 60 int current_stream_index_; | 82 int current_stream_index_; |
| 61 bool bitstream_converter_enabled_; | 83 bool bitstream_converter_enabled_; |
| 62 | 84 |
| 85 // The number of outstanding Read()'s on streams_[current_stream_index_]. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
||'ify code in comments (here and elsewhere).
| |
| 86 int pending_reads_; | |
| 87 | |
| 88 // A queue of callback objects passed to Read() calls on this object. | |
| 89 ReadCBQueue read_cb_queue_; | |
| 90 | |
| 91 // Callback passed to ChangeCurrentStream(). This is called & reset when the | |
| 92 // stream switch has completed. | |
| 93 PipelineStatusCB switch_cb_; | |
| 94 | |
| 95 // The index of the stream we are switching to. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
Document value while not switching (or that value
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 96 int switch_index_; | |
| 97 | |
| 98 // Helper object used to seek streams_|switch_index_| to a specific time. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
brackets instead of pipes
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 99 SeekHelper switch_seek_helper_; | |
| 100 | |
| 101 // The timestamp of the last buffered returned via a Read() callback. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
s/buffered/buffer/
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
| |
| 102 base::TimeDelta last_buffer_timestamp_; | |
| 103 | |
| 63 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerStream); | 104 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerStream); |
| 64 }; | 105 }; |
| 65 | 106 |
| 66 class AdaptiveDemuxer : public Demuxer { | 107 class AdaptiveDemuxer : public Demuxer { |
| 67 public: | 108 public: |
| 68 typedef std::vector<scoped_refptr<Demuxer> > DemuxerVector; | 109 typedef std::vector<scoped_refptr<Demuxer> > DemuxerVector; |
| 110 typedef std::vector<int> StreamIdVector; | |
| 69 | 111 |
| 70 // |demuxers| must be non-empty, and the index arguments must be valid indexes | 112 // |demuxers| must be non-empty, and the index arguments must be valid indexes |
| 71 // into |demuxers|, or -1 to indicate no demuxer is serving that type. | 113 // into |demuxers|, or -1 to indicate no demuxer is serving that type. |
| 72 AdaptiveDemuxer(DemuxerVector const& demuxers, | 114 AdaptiveDemuxer(DemuxerVector const& demuxers, |
| 73 int initial_audio_demuxer_index, | 115 int initial_audio_demuxer_index, |
| 74 int initial_video_demuxer_index); | 116 int initial_video_demuxer_index); |
| 75 virtual ~AdaptiveDemuxer(); | 117 virtual ~AdaptiveDemuxer(); |
| 76 | 118 |
| 77 // Change which demuxers the streams will use. | 119 // Change the to a different video stream. |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
English.
I think this is the first time you/we enf
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
Done.
For now I'm constraining code to video only
| |
| 78 void ChangeCurrentDemuxer(int audio_index, int video_index); | 120 void ChangeVideoStream(int video_id, const PipelineStatusCB& done_cb); |
| 121 | |
| 122 // Get the ID of the current video stream. | |
|
Ami GONE FROM CHROMIUM
2011/05/19 20:27:37
This and the next method: are they really necessar
acolwell GONE FROM CHROMIUM
2011/05/20 01:26:37
These were added so a StreamSwitchManager object c
| |
| 123 int GetCurrentVideoId() const; | |
| 124 | |
| 125 // Get all of the video stream IDs. | |
| 126 StreamIdVector GetVideoIds() const; | |
| 79 | 127 |
| 80 // Filter implementation. | 128 // Filter implementation. |
| 81 virtual void Stop(FilterCallback* callback); | 129 virtual void Stop(FilterCallback* callback); |
| 82 virtual void Seek(base::TimeDelta time, const FilterStatusCB& cb); | 130 virtual void Seek(base::TimeDelta time, const FilterStatusCB& cb); |
| 83 virtual void OnAudioRendererDisabled(); | 131 virtual void OnAudioRendererDisabled(); |
| 84 virtual void set_host(FilterHost* filter_host); | 132 virtual void set_host(FilterHost* filter_host); |
| 85 virtual void SetPlaybackRate(float playback_rate); | 133 virtual void SetPlaybackRate(float playback_rate); |
| 86 virtual void SetPreload(Preload preload); | 134 virtual void SetPreload(Preload preload); |
| 87 | 135 |
| 88 // Demuxer implementation. | 136 // Demuxer implementation. |
| 89 virtual scoped_refptr<DemuxerStream> GetStream(DemuxerStream::Type type); | 137 virtual scoped_refptr<DemuxerStream> GetStream(DemuxerStream::Type type); |
| 90 | 138 |
| 91 private: | 139 private: |
| 92 // Returns a pointer to the currently active demuxer of the given type. | 140 // Returns a pointer to the currently active demuxer of the given type. |
| 93 Demuxer* current_demuxer(DemuxerStream::Type type); | 141 Demuxer* current_demuxer(DemuxerStream::Type type); |
| 94 | 142 |
| 143 // Called when the AdaptiveDemuxerStream completes a stream switch. | |
| 144 void ChangeVideoStreamDone(int new_stream_index, | |
| 145 const PipelineStatusCB& done_cb, | |
| 146 PipelineStatus status); | |
| 147 | |
| 148 // Methods for SeekHelper. | |
| 149 // Initial method called when the AdaptiveDemuxerStream calls the SeekHelper. | |
| 150 void StartStreamSwitchSeek(DemuxerStream::Type type, | |
| 151 int stream_index, | |
| 152 const base::TimeDelta& seek_time, | |
| 153 const SeekHelperCB& seek_cb); | |
| 154 | |
| 155 // Called when the seek for index data initiated by StartStreamSwitchSeek() | |
| 156 // completes. | |
| 157 void OnIndexSeekDone(DemuxerStream::Type type, | |
| 158 int stream_index, | |
| 159 const base::TimeDelta& seek_time, | |
| 160 const SeekHelperCB& seek_cb, | |
| 161 PipelineStatus status); | |
| 162 | |
| 163 // Called when the stream seek initiated by StartStreamSwitchSeek() or | |
| 164 // OnIndexSeekDone() completes. | |
| 165 void OnStreamSeekDone(const base::TimeDelta& seek_point, | |
| 166 const SeekHelperCB& seek_cb, | |
| 167 PipelineStatus status); | |
| 168 | |
| 95 DemuxerVector demuxers_; | 169 DemuxerVector demuxers_; |
| 96 scoped_refptr<AdaptiveDemuxerStream> audio_stream_; | 170 scoped_refptr<AdaptiveDemuxerStream> audio_stream_; |
| 97 scoped_refptr<AdaptiveDemuxerStream> video_stream_; | 171 scoped_refptr<AdaptiveDemuxerStream> video_stream_; |
| 98 // Guards the members below. Only held for simple variable reads/writes, not | 172 // Guards the members below. Only held for simple variable reads/writes, not |
| 99 // during async operation. | 173 // during async operation. |
| 100 base::Lock lock_; | 174 mutable base::Lock lock_; |
| 101 int current_audio_demuxer_index_; | 175 int current_audio_demuxer_index_; |
| 102 int current_video_demuxer_index_; | 176 int current_video_demuxer_index_; |
| 177 float playback_rate_; | |
| 178 bool switch_pending_; | |
| 179 scoped_refptr<StreamSwitchManager> stream_switch_manager_; | |
| 103 | 180 |
| 104 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxer); | 181 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxer); |
| 105 }; | 182 }; |
| 106 | 183 |
| 107 // AdaptiveDemuxerFactory wraps an underlying DemuxerFactory that knows how to | 184 // AdaptiveDemuxerFactory wraps an underlying DemuxerFactory that knows how to |
| 108 // build demuxers for a single URL, and implements a primitive (for now) version | 185 // build demuxers for a single URL, and implements a primitive (for now) version |
| 109 // of multi-file manifests. The manifest is encoded in the |url| parameter to | 186 // of multi-file manifests. The manifest is encoded in the |url| parameter to |
| 110 // Build() as: | 187 // Build() as: |
| 111 // x-adaptive:<initial_audio_index>:<initial_video_index>:<URL>[^<URL>]* where | 188 // x-adaptive:<initial_audio_index>:<initial_video_index>:<URL>[^<URL>]* where |
| 112 // <URL>'s are "real" media URLs which are passed to the underlying | 189 // <URL>'s are "real" media URLs which are passed to the underlying |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 127 | 204 |
| 128 private: | 205 private: |
| 129 scoped_ptr<DemuxerFactory> delegate_factory_; | 206 scoped_ptr<DemuxerFactory> delegate_factory_; |
| 130 | 207 |
| 131 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerFactory); | 208 DISALLOW_IMPLICIT_CONSTRUCTORS(AdaptiveDemuxerFactory); |
| 132 }; | 209 }; |
| 133 | 210 |
| 134 } // namespace media | 211 } // namespace media |
| 135 | 212 |
| 136 #endif // MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ | 213 #endif // MEDIA_FILTERS_ADAPTIVE_DEMUXER_H_ |
| OLD | NEW |