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

Side by Side 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: _ 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698