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 // Implementation of Pipeline. | 5 // Implementation of Pipeline & PipelineStatusNotification (an async-to-sync |
| 6 // callback adapter). |
6 | 7 |
7 #ifndef MEDIA_BASE_PIPELINE_IMPL_H_ | 8 #ifndef MEDIA_BASE_PIPELINE_IMPL_H_ |
8 #define MEDIA_BASE_PIPELINE_IMPL_H_ | 9 #define MEDIA_BASE_PIPELINE_IMPL_H_ |
9 | 10 |
10 #include <set> | 11 #include <set> |
11 #include <string> | 12 #include <string> |
12 #include <vector> | 13 #include <vector> |
13 | 14 |
14 #include "base/gtest_prod_util.h" | 15 #include "base/gtest_prod_util.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/ref_counted.h" | 17 #include "base/ref_counted.h" |
17 #include "base/scoped_ptr.h" | 18 #include "base/scoped_ptr.h" |
| 19 #include "base/synchronization/condition_variable.h" |
| 20 #include "base/synchronization/lock.h" |
18 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
19 #include "base/time.h" | 22 #include "base/time.h" |
20 #include "media/base/clock.h" | 23 #include "media/base/clock.h" |
21 #include "media/base/composite_filter.h" | 24 #include "media/base/composite_filter.h" |
22 #include "media/base/filter_host.h" | 25 #include "media/base/filter_host.h" |
23 #include "media/base/pipeline.h" | 26 #include "media/base/pipeline.h" |
24 | 27 |
25 namespace media { | 28 namespace media { |
26 | 29 |
| 30 // Adapter for using asynchronous Pipeline methods in code that wants to run |
| 31 // synchronously. To use, construct an instance of this class and pass the |
| 32 // |Callback()| to the Pipeline method requiring a callback. Then Wait() for |
| 33 // the callback to get fired and call status() to see what the callback's |
| 34 // argument was. This object is for one-time use; call |Callback()| exactly |
| 35 // once. |
| 36 class PipelineStatusNotification { |
| 37 public: |
| 38 PipelineStatusNotification(); |
| 39 ~PipelineStatusNotification(); |
| 40 |
| 41 // See class-level comment for usage. |
| 42 media::PipelineStatusCallback* Callback(); |
| 43 void Notify(media::PipelineStatus status); |
| 44 void Wait(); |
| 45 media::PipelineStatus status(); |
| 46 |
| 47 private: |
| 48 base::Lock lock_; |
| 49 base::ConditionVariable cv_; |
| 50 media::PipelineStatus status_; |
| 51 bool notified_; |
| 52 scoped_ptr<media::PipelineStatusCallback> callback_; |
| 53 |
| 54 DISALLOW_COPY_AND_ASSIGN(PipelineStatusNotification); |
| 55 }; |
27 | 56 |
28 // PipelineImpl runs the media pipeline. Filters are created and called on the | 57 // PipelineImpl runs the media pipeline. Filters are created and called on the |
29 // message loop injected into this object. PipelineImpl works like a state | 58 // message loop injected into this object. PipelineImpl works like a state |
30 // machine to perform asynchronous initialization, pausing, seeking and playing. | 59 // machine to perform asynchronous initialization, pausing, seeking and playing. |
31 // | 60 // |
32 // Here's a state diagram that describes the lifetime of this object. | 61 // Here's a state diagram that describes the lifetime of this object. |
33 // | 62 // |
34 // [ *Created ] [ Stopped ] | 63 // [ *Created ] [ Stopped ] |
35 // | Start() ^ | 64 // | Start() ^ |
36 // V SetError() | | 65 // V SetError() | |
(...skipping 23 matching lines...) Expand all Loading... |
60 // playing the media. | 89 // playing the media. |
61 // | 90 // |
62 // If any error ever happens, this object will transition to the "Error" state | 91 // If any error ever happens, this object will transition to the "Error" state |
63 // from any state. If Stop() is ever called, this object will transition to | 92 // from any state. If Stop() is ever called, this object will transition to |
64 // "Stopped" state. | 93 // "Stopped" state. |
65 class PipelineImpl : public Pipeline, public FilterHost { | 94 class PipelineImpl : public Pipeline, public FilterHost { |
66 public: | 95 public: |
67 explicit PipelineImpl(MessageLoop* message_loop); | 96 explicit PipelineImpl(MessageLoop* message_loop); |
68 | 97 |
69 // Pipeline implementation. | 98 // Pipeline implementation. |
70 virtual void Init(PipelineCallback* ended_callback, | 99 virtual void Init(PipelineStatusCallback* ended_callback, |
71 PipelineCallback* error_callback, | 100 PipelineStatusCallback* error_callback, |
72 PipelineCallback* network_callback); | 101 PipelineStatusCallback* network_callback); |
73 virtual bool Start(FilterCollection* filter_collection, | 102 virtual bool Start(FilterCollection* filter_collection, |
74 const std::string& uri, | 103 const std::string& uri, |
75 PipelineCallback* start_callback); | 104 PipelineStatusCallback* start_callback); |
76 virtual void Stop(PipelineCallback* stop_callback); | 105 virtual void Stop(PipelineStatusCallback* stop_callback); |
77 virtual void Seek(base::TimeDelta time, PipelineCallback* seek_callback); | 106 virtual void Seek(base::TimeDelta time, |
| 107 PipelineStatusCallback* seek_callback); |
78 virtual bool IsRunning() const; | 108 virtual bool IsRunning() const; |
79 virtual bool IsInitialized() const; | 109 virtual bool IsInitialized() const; |
80 virtual bool IsNetworkActive() const; | 110 virtual bool IsNetworkActive() const; |
81 virtual bool HasAudio() const; | 111 virtual bool HasAudio() const; |
82 virtual bool HasVideo() const; | 112 virtual bool HasVideo() const; |
83 virtual float GetPlaybackRate() const; | 113 virtual float GetPlaybackRate() const; |
84 virtual void SetPlaybackRate(float playback_rate); | 114 virtual void SetPlaybackRate(float playback_rate); |
85 virtual float GetVolume() const; | 115 virtual float GetVolume() const; |
86 virtual void SetVolume(float volume); | 116 virtual void SetVolume(float volume); |
87 virtual base::TimeDelta GetCurrentTime() const; | 117 virtual base::TimeDelta GetCurrentTime() const; |
88 virtual base::TimeDelta GetBufferedTime(); | 118 virtual base::TimeDelta GetBufferedTime(); |
89 virtual base::TimeDelta GetMediaDuration() const; | 119 virtual base::TimeDelta GetMediaDuration() const; |
90 virtual int64 GetBufferedBytes() const; | 120 virtual int64 GetBufferedBytes() const; |
91 virtual int64 GetTotalBytes() const; | 121 virtual int64 GetTotalBytes() const; |
92 virtual void GetVideoSize(size_t* width_out, size_t* height_out) const; | 122 virtual void GetVideoSize(size_t* width_out, size_t* height_out) const; |
93 virtual bool IsStreaming() const; | 123 virtual bool IsStreaming() const; |
94 virtual bool IsLoaded() const; | 124 virtual bool IsLoaded() const; |
95 virtual PipelineError GetError() const; | |
96 virtual PipelineStatistics GetStatistics() const; | 125 virtual PipelineStatistics GetStatistics() const; |
97 | 126 |
98 void SetClockForTesting(Clock* clock); | 127 void SetClockForTesting(Clock* clock); |
99 | 128 |
100 private: | 129 private: |
101 // Pipeline states, as described above. | 130 // Pipeline states, as described above. |
102 enum State { | 131 enum State { |
103 kCreated, | 132 kCreated, |
104 kInitDemuxer, | 133 kInitDemuxer, |
105 kInitAudioDecoder, | 134 kInitAudioDecoder, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 void FinishInitialization(); | 177 void FinishInitialization(); |
149 | 178 |
150 // Returns true if the given state is one that transitions to a new state | 179 // Returns true if the given state is one that transitions to a new state |
151 // after iterating through each filter. | 180 // after iterating through each filter. |
152 static bool TransientState(State state); | 181 static bool TransientState(State state); |
153 | 182 |
154 // Given the current state, returns the next state. | 183 // Given the current state, returns the next state. |
155 State FindNextState(State current); | 184 State FindNextState(State current); |
156 | 185 |
157 // FilterHost implementation. | 186 // FilterHost implementation. |
158 virtual void SetError(PipelineError error); | 187 virtual void SetError(PipelineStatus error); |
159 virtual base::TimeDelta GetTime() const; | 188 virtual base::TimeDelta GetTime() const; |
160 virtual base::TimeDelta GetDuration() const; | 189 virtual base::TimeDelta GetDuration() const; |
161 virtual void SetTime(base::TimeDelta time); | 190 virtual void SetTime(base::TimeDelta time); |
162 virtual void SetDuration(base::TimeDelta duration); | 191 virtual void SetDuration(base::TimeDelta duration); |
163 virtual void SetBufferedTime(base::TimeDelta buffered_time); | 192 virtual void SetBufferedTime(base::TimeDelta buffered_time); |
164 virtual void SetTotalBytes(int64 total_bytes); | 193 virtual void SetTotalBytes(int64 total_bytes); |
165 virtual void SetBufferedBytes(int64 buffered_bytes); | 194 virtual void SetBufferedBytes(int64 buffered_bytes); |
166 virtual void SetVideoSize(size_t width, size_t height); | 195 virtual void SetVideoSize(size_t width, size_t height); |
167 virtual void SetStreaming(bool streamed); | 196 virtual void SetStreaming(bool streamed); |
168 virtual void SetLoaded(bool loaded); | 197 virtual void SetLoaded(bool loaded); |
(...skipping 14 matching lines...) Expand all Loading... |
183 void OnTeardownStateTransition(); | 212 void OnTeardownStateTransition(); |
184 | 213 |
185 // Callback executed by filters to update statistics. | 214 // Callback executed by filters to update statistics. |
186 void OnUpdateStatistics(const PipelineStatistics& stats); | 215 void OnUpdateStatistics(const PipelineStatistics& stats); |
187 | 216 |
188 // The following "task" methods correspond to the public methods, but these | 217 // The following "task" methods correspond to the public methods, but these |
189 // methods are run as the result of posting a task to the PipelineInternal's | 218 // methods are run as the result of posting a task to the PipelineInternal's |
190 // message loop. | 219 // message loop. |
191 void StartTask(FilterCollection* filter_collection, | 220 void StartTask(FilterCollection* filter_collection, |
192 const std::string& url, | 221 const std::string& url, |
193 PipelineCallback* start_callback); | 222 PipelineStatusCallback* start_callback); |
194 | 223 |
195 // InitializeTask() performs initialization in multiple passes. It is executed | 224 // InitializeTask() performs initialization in multiple passes. It is executed |
196 // as a result of calling Start() or InitializationComplete() that advances | 225 // as a result of calling Start() or InitializationComplete() that advances |
197 // initialization to the next state. It works as a hub of state transition for | 226 // initialization to the next state. It works as a hub of state transition for |
198 // initialization. | 227 // initialization. |
199 void InitializeTask(); | 228 void InitializeTask(); |
200 | 229 |
201 // Stops and destroys all filters, placing the pipeline in the kStopped state. | 230 // Stops and destroys all filters, placing the pipeline in the kStopped state. |
202 void StopTask(PipelineCallback* stop_callback); | 231 void StopTask(PipelineStatusCallback* stop_callback); |
203 | 232 |
204 // Carries out stopping and destroying all filters, placing the pipeline in | 233 // Carries out stopping and destroying all filters, placing the pipeline in |
205 // the kError state. | 234 // the kError state. |
206 void ErrorChangedTask(PipelineError error); | 235 void ErrorChangedTask(PipelineStatus error); |
207 | 236 |
208 // Carries out notifying filters that the playback rate has changed. | 237 // Carries out notifying filters that the playback rate has changed. |
209 void PlaybackRateChangedTask(float playback_rate); | 238 void PlaybackRateChangedTask(float playback_rate); |
210 | 239 |
211 // Carries out notifying filters that the volume has changed. | 240 // Carries out notifying filters that the volume has changed. |
212 void VolumeChangedTask(float volume); | 241 void VolumeChangedTask(float volume); |
213 | 242 |
214 // Carries out notifying filters that we are seeking to a new timestamp. | 243 // Carries out notifying filters that we are seeking to a new timestamp. |
215 void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback); | 244 void SeekTask(base::TimeDelta time, PipelineStatusCallback* seek_callback); |
216 | 245 |
217 // Carries out handling a notification from a filter that it has ended. | 246 // Carries out handling a notification from a filter that it has ended. |
218 void NotifyEndedTask(); | 247 void NotifyEndedTask(); |
219 | 248 |
220 // Carries out handling a notification of network event. | 249 // Carries out handling a notification of network event. |
221 void NotifyNetworkEventTask(); | 250 void NotifyNetworkEventTask(); |
222 | 251 |
223 // Carries out disabling the audio renderer. | 252 // Carries out disabling the audio renderer. |
224 void DisableAudioRendererTask(); | 253 void DisableAudioRendererTask(); |
225 | 254 |
(...skipping 12 matching lines...) Expand all Loading... |
238 // Internal methods used in the implementation of the pipeline thread. All | 267 // Internal methods used in the implementation of the pipeline thread. All |
239 // of these methods are only called on the pipeline thread. | 268 // of these methods are only called on the pipeline thread. |
240 | 269 |
241 // PrepareFilter() creates the filter's thread and injects a FilterHost and | 270 // PrepareFilter() creates the filter's thread and injects a FilterHost and |
242 // MessageLoop. | 271 // MessageLoop. |
243 bool PrepareFilter(scoped_refptr<Filter> filter); | 272 bool PrepareFilter(scoped_refptr<Filter> filter); |
244 | 273 |
245 // The following initialize methods are used to select a specific type of | 274 // The following initialize methods are used to select a specific type of |
246 // Filter object from FilterCollection and initialize it asynchronously. | 275 // Filter object from FilterCollection and initialize it asynchronously. |
247 void InitializeDemuxer(); | 276 void InitializeDemuxer(); |
248 void OnDemuxerBuilt(PipelineError error, Demuxer* demuxer); | 277 void OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer); |
249 | 278 |
250 // Returns true if the asynchronous action of creating decoder has started. | 279 // Returns true if the asynchronous action of creating decoder has started. |
251 // Returns false if this method did nothing because the corresponding | 280 // Returns false if this method did nothing because the corresponding |
252 // audio/video stream does not exist. | 281 // audio/video stream does not exist. |
253 bool InitializeAudioDecoder(const scoped_refptr<Demuxer>& demuxer); | 282 bool InitializeAudioDecoder(const scoped_refptr<Demuxer>& demuxer); |
254 bool InitializeVideoDecoder(const scoped_refptr<Demuxer>& demuxer); | 283 bool InitializeVideoDecoder(const scoped_refptr<Demuxer>& demuxer); |
255 | 284 |
256 // Initializes a renderer and connects it with decoder. Returns true if the | 285 // Initializes a renderer and connects it with decoder. Returns true if the |
257 // asynchronous action of creating renderer has started. Returns | 286 // asynchronous action of creating renderer has started. Returns |
258 // false if this method did nothing because the corresponding audio/video | 287 // false if this method did nothing because the corresponding audio/video |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 373 |
345 // If this value is set to true, then |clock_| is paused and we are waiting | 374 // If this value is set to true, then |clock_| is paused and we are waiting |
346 // for an update of the clock greater than or equal to the elapsed time to | 375 // for an update of the clock greater than or equal to the elapsed time to |
347 // start the clock. | 376 // start the clock. |
348 bool waiting_for_clock_update_; | 377 bool waiting_for_clock_update_; |
349 | 378 |
350 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that | 379 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that |
351 // the pipeline is operating correctly. Any other value indicates that the | 380 // the pipeline is operating correctly. Any other value indicates that the |
352 // pipeline is stopped or is stopping. Clients can call the Stop() method to | 381 // pipeline is stopped or is stopping. Clients can call the Stop() method to |
353 // reset the pipeline state, and restore this to PIPELINE_OK. | 382 // reset the pipeline state, and restore this to PIPELINE_OK. |
354 PipelineError error_; | 383 PipelineStatus status_; |
355 | 384 |
356 // Whether the media contains rendered audio and video streams. | 385 // Whether the media contains rendered audio and video streams. |
357 bool has_audio_; | 386 bool has_audio_; |
358 bool has_video_; | 387 bool has_video_; |
359 | 388 |
360 // The following data members are only accessed by tasks posted to | 389 // The following data members are only accessed by tasks posted to |
361 // |message_loop_|. | 390 // |message_loop_|. |
362 | 391 |
363 // Member that tracks the current state. | 392 // Member that tracks the current state. |
364 State state_; | 393 State state_; |
(...skipping 14 matching lines...) Expand all Loading... |
379 // TODO(vrk): This is a hack. | 408 // TODO(vrk): This is a hack. |
380 base::TimeDelta max_buffered_time_; | 409 base::TimeDelta max_buffered_time_; |
381 | 410 |
382 // Filter collection as passed in by Start(). | 411 // Filter collection as passed in by Start(). |
383 scoped_ptr<FilterCollection> filter_collection_; | 412 scoped_ptr<FilterCollection> filter_collection_; |
384 | 413 |
385 // URL for the data source as passed in by Start(). | 414 // URL for the data source as passed in by Start(). |
386 std::string url_; | 415 std::string url_; |
387 | 416 |
388 // Callbacks for various pipeline operations. | 417 // Callbacks for various pipeline operations. |
389 scoped_ptr<PipelineCallback> seek_callback_; | 418 scoped_ptr<PipelineStatusCallback> seek_callback_; |
390 scoped_ptr<PipelineCallback> stop_callback_; | 419 scoped_ptr<PipelineStatusCallback> stop_callback_; |
391 scoped_ptr<PipelineCallback> ended_callback_; | 420 scoped_ptr<PipelineStatusCallback> ended_callback_; |
392 scoped_ptr<PipelineCallback> error_callback_; | 421 scoped_ptr<PipelineStatusCallback> error_callback_; |
393 scoped_ptr<PipelineCallback> network_callback_; | 422 scoped_ptr<PipelineStatusCallback> network_callback_; |
394 | 423 |
395 // Reference to the filter(s) that constitute the pipeline. | 424 // Reference to the filter(s) that constitute the pipeline. |
396 scoped_refptr<Filter> pipeline_filter_; | 425 scoped_refptr<Filter> pipeline_filter_; |
397 | 426 |
398 // Renderer references used for setting the volume and determining | 427 // Renderer references used for setting the volume and determining |
399 // when playback has finished. | 428 // when playback has finished. |
400 scoped_refptr<AudioRenderer> audio_renderer_; | 429 scoped_refptr<AudioRenderer> audio_renderer_; |
401 scoped_refptr<VideoRenderer> video_renderer_; | 430 scoped_refptr<VideoRenderer> video_renderer_; |
402 | 431 |
403 // Helper class that stores filter references during pipeline | 432 // Helper class that stores filter references during pipeline |
404 // initialization. | 433 // initialization. |
405 class PipelineInitState; | 434 class PipelineInitState; |
406 scoped_ptr<PipelineInitState> pipeline_init_state_; | 435 scoped_ptr<PipelineInitState> pipeline_init_state_; |
407 | 436 |
408 // Statistics. | 437 // Statistics. |
409 PipelineStatistics statistics_; | 438 PipelineStatistics statistics_; |
410 | 439 |
411 FRIEND_TEST_ALL_PREFIXES(PipelineImplTest, GetBufferedTime); | 440 FRIEND_TEST_ALL_PREFIXES(PipelineImplTest, GetBufferedTime); |
412 | 441 |
413 DISALLOW_COPY_AND_ASSIGN(PipelineImpl); | 442 DISALLOW_COPY_AND_ASSIGN(PipelineImpl); |
414 }; | 443 }; |
415 | 444 |
416 } // namespace media | 445 } // namespace media |
417 | 446 |
418 #endif // MEDIA_BASE_PIPELINE_IMPL_H_ | 447 #endif // MEDIA_BASE_PIPELINE_IMPL_H_ |
OLD | NEW |