OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #ifndef MEDIA_BASE_PIPELINE_H_ | 5 #ifndef MEDIA_BASE_PIPELINE_H_ |
6 #define MEDIA_BASE_PIPELINE_H_ | 6 #define MEDIA_BASE_PIPELINE_H_ |
7 | 7 |
| 8 #include <string> |
| 9 |
8 #include "base/gtest_prod_util.h" | 10 #include "base/gtest_prod_util.h" |
9 #include "base/memory/weak_ptr.h" | 11 #include "base/memory/weak_ptr.h" |
| 12 #include "base/synchronization/condition_variable.h" |
10 #include "base/synchronization/lock.h" | 13 #include "base/synchronization/lock.h" |
11 #include "base/threading/thread_checker.h" | 14 #include "base/threading/thread_checker.h" |
12 #include "base/time/default_tick_clock.h" | 15 #include "base/time/default_tick_clock.h" |
| 16 #include "media/base/audio_renderer.h" |
13 #include "media/base/buffering_state.h" | 17 #include "media/base/buffering_state.h" |
14 #include "media/base/demuxer.h" | 18 #include "media/base/demuxer.h" |
15 #include "media/base/media_export.h" | 19 #include "media/base/media_export.h" |
16 #include "media/base/pipeline_status.h" | 20 #include "media/base/pipeline_status.h" |
17 #include "media/base/ranges.h" | 21 #include "media/base/ranges.h" |
18 #include "media/base/serial_runner.h" | 22 #include "media/base/serial_runner.h" |
19 #include "media/base/video_rotation.h" | 23 #include "media/base/video_rotation.h" |
20 #include "ui/gfx/size.h" | 24 #include "ui/gfx/size.h" |
21 | 25 |
22 namespace base { | 26 namespace base { |
23 class SingleThreadTaskRunner; | 27 class SingleThreadTaskRunner; |
24 class TimeDelta; | 28 class TimeDelta; |
25 } | 29 } |
26 | 30 |
27 namespace media { | 31 namespace media { |
28 | 32 |
29 class FilterCollection; | 33 class FilterCollection; |
30 class MediaLog; | 34 class MediaLog; |
31 class Renderer; | |
32 class TextRenderer; | 35 class TextRenderer; |
33 class TextTrackConfig; | 36 class TextTrackConfig; |
34 class TimeDeltaInterpolator; | 37 class TimeDeltaInterpolator; |
| 38 class TimeSource; |
| 39 class VideoRenderer; |
35 | 40 |
36 // Metadata describing a pipeline once it has been initialized. | 41 // Metadata describing a pipeline once it has been initialized. |
37 struct PipelineMetadata { | 42 struct PipelineMetadata { |
38 PipelineMetadata() | 43 PipelineMetadata() |
39 : has_audio(false), has_video(false), video_rotation(VIDEO_ROTATION_0) {} | 44 : has_audio(false), has_video(false), video_rotation(VIDEO_ROTATION_0) {} |
40 | 45 |
41 bool has_audio; | 46 bool has_audio; |
42 bool has_video; | 47 bool has_video; |
43 gfx::Size natural_size; | 48 gfx::Size natural_size; |
44 VideoRotation video_rotation; | 49 VideoRotation video_rotation; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // been determined yet, then returns 0. | 171 // been determined yet, then returns 0. |
167 base::TimeDelta GetMediaDuration() const; | 172 base::TimeDelta GetMediaDuration() const; |
168 | 173 |
169 // Return true if loading progress has been made since the last time this | 174 // Return true if loading progress has been made since the last time this |
170 // method was called. | 175 // method was called. |
171 bool DidLoadingProgress(); | 176 bool DidLoadingProgress(); |
172 | 177 |
173 // Gets the current pipeline statistics. | 178 // Gets the current pipeline statistics. |
174 PipelineStatistics GetStatistics() const; | 179 PipelineStatistics GetStatistics() const; |
175 | 180 |
| 181 void set_underflow_disabled_for_testing(bool disabled) { |
| 182 underflow_disabled_for_testing_ = disabled; |
| 183 } |
| 184 void SetTimeDeltaInterpolatorForTesting(TimeDeltaInterpolator* interpolator); |
176 void SetErrorForTesting(PipelineStatus status); | 185 void SetErrorForTesting(PipelineStatus status); |
177 bool HasWeakPtrsForTesting() const; | 186 bool HasWeakPtrsForTesting() const; |
178 | 187 |
179 private: | 188 private: |
180 FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTimeRanges); | 189 FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTimeRanges); |
181 FRIEND_TEST_ALL_PREFIXES(PipelineTest, EndedCallback); | 190 FRIEND_TEST_ALL_PREFIXES(PipelineTest, EndedCallback); |
182 FRIEND_TEST_ALL_PREFIXES(PipelineTest, AudioStreamShorterThanVideo); | 191 FRIEND_TEST_ALL_PREFIXES(PipelineTest, AudioStreamShorterThanVideo); |
183 friend class MediaLog; | 192 friend class MediaLog; |
184 | 193 |
185 // Pipeline states, as described above. | 194 // Pipeline states, as described above. |
186 enum State { | 195 enum State { |
187 kCreated, | 196 kCreated, |
188 kInitDemuxer, | 197 kInitDemuxer, |
189 kInitRenderer, | 198 kInitAudioRenderer, |
| 199 kInitVideoRenderer, |
190 kSeeking, | 200 kSeeking, |
191 kPlaying, | 201 kPlaying, |
192 kStopping, | 202 kStopping, |
193 kStopped, | 203 kStopped, |
194 }; | 204 }; |
195 | 205 |
196 // Updates |state_|. All state transitions should use this call. | 206 // Updates |state_|. All state transitions should use this call. |
197 void SetState(State next_state); | 207 void SetState(State next_state); |
198 | 208 |
199 static const char* GetStateString(State state); | 209 static const char* GetStateString(State state); |
(...skipping 12 matching lines...) Expand all Loading... |
212 const TextTrackConfig& config) OVERRIDE; | 222 const TextTrackConfig& config) OVERRIDE; |
213 virtual void RemoveTextStream(DemuxerStream* text_stream) OVERRIDE; | 223 virtual void RemoveTextStream(DemuxerStream* text_stream) OVERRIDE; |
214 | 224 |
215 // Callback executed when a rendering error happened, initiating the teardown | 225 // Callback executed when a rendering error happened, initiating the teardown |
216 // sequence. | 226 // sequence. |
217 void OnError(PipelineStatus error); | 227 void OnError(PipelineStatus error); |
218 | 228 |
219 // Callback executed by filters to update statistics. | 229 // Callback executed by filters to update statistics. |
220 void OnUpdateStatistics(const PipelineStatistics& stats); | 230 void OnUpdateStatistics(const PipelineStatistics& stats); |
221 | 231 |
| 232 // Callback executed by audio renderer to update clock time. |
| 233 void OnAudioTimeUpdate(base::TimeDelta time, base::TimeDelta max_time); |
| 234 |
| 235 // Callback executed by video renderer to update clock time. |
| 236 void OnVideoTimeUpdate(base::TimeDelta max_time); |
| 237 |
222 // The following "task" methods correspond to the public methods, but these | 238 // The following "task" methods correspond to the public methods, but these |
223 // methods are run as the result of posting a task to the Pipeline's | 239 // methods are run as the result of posting a task to the Pipeline's |
224 // task runner. | 240 // task runner. |
225 void StartTask(); | 241 void StartTask(); |
226 | 242 |
227 // Stops and destroys all filters, placing the pipeline in the kStopped state. | 243 // Stops and destroys all filters, placing the pipeline in the kStopped state. |
228 void StopTask(const base::Closure& stop_cb); | 244 void StopTask(const base::Closure& stop_cb); |
229 | 245 |
230 // Carries out stopping and destroying all filters, placing the pipeline in | 246 // Carries out stopping and destroying all filters, placing the pipeline in |
231 // the kStopped state. | 247 // the kStopped state. |
232 void ErrorChangedTask(PipelineStatus error); | 248 void ErrorChangedTask(PipelineStatus error); |
233 | 249 |
234 // Carries out notifying filters that the playback rate has changed. | 250 // Carries out notifying filters that the playback rate has changed. |
235 void PlaybackRateChangedTask(float playback_rate); | 251 void PlaybackRateChangedTask(float playback_rate); |
236 | 252 |
237 // Carries out notifying filters that the volume has changed. | 253 // Carries out notifying filters that the volume has changed. |
238 void VolumeChangedTask(float volume); | 254 void VolumeChangedTask(float volume); |
239 | 255 |
240 // Carries out notifying filters that we are seeking to a new timestamp. | 256 // Carries out notifying filters that we are seeking to a new timestamp. |
241 void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_cb); | 257 void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_cb); |
242 | 258 |
243 // Callbacks executed when a renderer has ended. | 259 // Callbacks executed when a renderer has ended. |
244 void OnRendererEnded(); | 260 void OnAudioRendererEnded(); |
| 261 void OnVideoRendererEnded(); |
245 void OnTextRendererEnded(); | 262 void OnTextRendererEnded(); |
246 void RunEndedCallbackIfNeeded(); | 263 void RunEndedCallbackIfNeeded(); |
247 | 264 |
248 // Carries out adding a new text stream to the text renderer. | 265 // Carries out adding a new text stream to the text renderer. |
249 void AddTextStreamTask(DemuxerStream* text_stream, | 266 void AddTextStreamTask(DemuxerStream* text_stream, |
250 const TextTrackConfig& config); | 267 const TextTrackConfig& config); |
251 | 268 |
252 // Carries out removing a text stream from the text renderer. | 269 // Carries out removing a text stream from the text renderer. |
253 void RemoveTextStreamTask(DemuxerStream* text_stream); | 270 void RemoveTextStreamTask(DemuxerStream* text_stream); |
254 | 271 |
255 // Kicks off initialization for each media object, executing |done_cb| with | 272 // Kicks off initialization for each media object, executing |done_cb| with |
256 // the result when completed. | 273 // the result when completed. |
257 void InitializeDemuxer(const PipelineStatusCB& done_cb); | 274 void InitializeDemuxer(const PipelineStatusCB& done_cb); |
258 void InitializeRenderer(const PipelineStatusCB& done_cb); | 275 void InitializeAudioRenderer(const PipelineStatusCB& done_cb); |
| 276 void InitializeVideoRenderer(const PipelineStatusCB& done_cb); |
| 277 |
| 278 // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask(). |
| 279 // When we start to tear down the pipeline, we will consider two cases: |
| 280 // 1. when pipeline has not been initialized, we will transit to stopping |
| 281 // state first. |
| 282 // 2. when pipeline has been initialized, we will first transit to pausing |
| 283 // => flushing => stopping => stopped state. |
| 284 // This will remove the race condition during stop between filters. |
| 285 void TearDownPipeline(); |
| 286 |
| 287 // Compute the time corresponding to a byte offset. |
| 288 base::TimeDelta TimeForByteOffset_Locked(int64 byte_offset) const; |
259 | 289 |
260 void OnStateTransition(PipelineStatus status); | 290 void OnStateTransition(PipelineStatus status); |
261 void StateTransitionTask(PipelineStatus status); | 291 void StateTransitionTask(PipelineStatus status); |
262 | 292 |
263 // Initiates an asynchronous pause-flush-seek-preroll call sequence | 293 // Initiates an asynchronous pause-flush-seek-preroll call sequence |
264 // executing |done_cb| with the final status when completed. | 294 // executing |done_cb| with the final status when completed. |
265 void DoSeek(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb); | 295 void DoSeek(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb); |
266 | 296 |
267 // Initiates an asynchronous pause-flush-stop call sequence executing | 297 // Initiates an asynchronous pause-flush-stop call sequence executing |
268 // |done_cb| when completed. | 298 // |done_cb| when completed. |
269 void DoStop(const PipelineStatusCB& done_cb); | 299 void DoStop(const PipelineStatusCB& done_cb); |
270 void OnStopCompleted(PipelineStatus status); | 300 void OnStopCompleted(PipelineStatus status); |
271 | 301 |
272 void BufferingStateChanged(BufferingState new_buffering_state); | 302 // Collection of callback methods and helpers for tracking changes in |
| 303 // buffering state and transition from paused/underflow states and playing |
| 304 // states. |
| 305 // |
| 306 // While in the kPlaying state: |
| 307 // - A waiting to non-waiting transition indicates preroll has completed |
| 308 // and StartPlayback() should be called |
| 309 // - A non-waiting to waiting transition indicates underflow has occurred |
| 310 // and PausePlayback() should be called |
| 311 void BufferingStateChanged(BufferingState* buffering_state, |
| 312 BufferingState new_buffering_state); |
| 313 bool WaitingForEnoughData() const; |
| 314 void PausePlayback(); |
| 315 void StartPlayback(); |
| 316 |
| 317 void PauseClockAndStopTicking_Locked(); |
| 318 void StartClockIfWaitingForTimeUpdate_Locked(); |
273 | 319 |
274 // Task runner used to execute pipeline tasks. | 320 // Task runner used to execute pipeline tasks. |
275 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 321 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
276 | 322 |
277 // MediaLog to which to log events. | 323 // MediaLog to which to log events. |
278 scoped_refptr<MediaLog> media_log_; | 324 scoped_refptr<MediaLog> media_log_; |
279 | 325 |
280 // Lock used to serialize access for the following data members. | 326 // Lock used to serialize access for the following data members. |
281 mutable base::Lock lock_; | 327 mutable base::Lock lock_; |
282 | 328 |
(...skipping 13 matching lines...) Expand all Loading... |
296 float volume_; | 342 float volume_; |
297 | 343 |
298 // Current playback rate (>= 0.0f). This value is set immediately via | 344 // Current playback rate (>= 0.0f). This value is set immediately via |
299 // SetPlaybackRate() and a task is dispatched on the task runner to notify | 345 // SetPlaybackRate() and a task is dispatched on the task runner to notify |
300 // the filters. | 346 // the filters. |
301 float playback_rate_; | 347 float playback_rate_; |
302 | 348 |
303 // Current duration as reported by |demuxer_|. | 349 // Current duration as reported by |demuxer_|. |
304 base::TimeDelta duration_; | 350 base::TimeDelta duration_; |
305 | 351 |
| 352 // base::TickClock used by |interpolator_|. |
| 353 base::DefaultTickClock default_tick_clock_; |
| 354 |
| 355 // Tracks the most recent media time update and provides interpolated values |
| 356 // as playback progresses. |
| 357 scoped_ptr<TimeDeltaInterpolator> interpolator_; |
| 358 |
| 359 enum InterpolationState { |
| 360 // Audio (if present) is not rendering. Time isn't being interpolated. |
| 361 INTERPOLATION_STOPPED, |
| 362 |
| 363 // Audio (if present) is rendering. Time isn't being interpolated. |
| 364 INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE, |
| 365 |
| 366 // Audio (if present) is rendering. Time is being interpolated. |
| 367 INTERPOLATION_STARTED, |
| 368 }; |
| 369 |
| 370 InterpolationState interpolation_state_; |
| 371 |
306 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that | 372 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that |
307 // the pipeline is operating correctly. Any other value indicates that the | 373 // the pipeline is operating correctly. Any other value indicates that the |
308 // pipeline is stopped or is stopping. Clients can call the Stop() method to | 374 // pipeline is stopped or is stopping. Clients can call the Stop() method to |
309 // reset the pipeline state, and restore this to PIPELINE_OK. | 375 // reset the pipeline state, and restore this to PIPELINE_OK. |
310 PipelineStatus status_; | 376 PipelineStatus status_; |
311 | 377 |
312 // The following data members are only accessed by tasks posted to | 378 // The following data members are only accessed by tasks posted to |
313 // |task_runner_|. | 379 // |task_runner_|. |
314 | 380 |
315 bool is_initialized_; | |
316 | |
317 // Member that tracks the current state. | 381 // Member that tracks the current state. |
318 State state_; | 382 State state_; |
319 | 383 |
320 // The timestamp to start playback from after starting/seeking has completed. | 384 // The timestamp to start playback from after starting/seeking has completed. |
321 base::TimeDelta start_timestamp_; | 385 base::TimeDelta start_timestamp_; |
322 | 386 |
323 // Whether we've received the audio/video/text ended events. | 387 // Whether we've received the audio/video/text ended events. |
324 bool renderer_ended_; | 388 bool audio_ended_; |
325 bool text_renderer_ended_; | 389 bool video_ended_; |
| 390 bool text_ended_; |
| 391 |
| 392 BufferingState audio_buffering_state_; |
| 393 BufferingState video_buffering_state_; |
326 | 394 |
327 // Temporary callback used for Start() and Seek(). | 395 // Temporary callback used for Start() and Seek(). |
328 PipelineStatusCB seek_cb_; | 396 PipelineStatusCB seek_cb_; |
329 | 397 |
330 // Temporary callback used for Stop(). | 398 // Temporary callback used for Stop(). |
331 base::Closure stop_cb_; | 399 base::Closure stop_cb_; |
332 | 400 |
333 // Permanent callbacks passed in via Start(). | 401 // Permanent callbacks passed in via Start(). |
334 base::Closure ended_cb_; | 402 base::Closure ended_cb_; |
335 PipelineStatusCB error_cb_; | 403 PipelineStatusCB error_cb_; |
336 PipelineMetadataCB metadata_cb_; | 404 PipelineMetadataCB metadata_cb_; |
337 BufferingStateCB buffering_state_cb_; | 405 BufferingStateCB buffering_state_cb_; |
338 base::Closure duration_change_cb_; | 406 base::Closure duration_change_cb_; |
339 | 407 |
340 // Contains the demuxer and renderers to use when initializing. | 408 // Contains the demuxer and renderers to use when initializing. |
341 scoped_ptr<FilterCollection> filter_collection_; | 409 scoped_ptr<FilterCollection> filter_collection_; |
342 | 410 |
343 // Holds the initialized demuxer. Used for seeking. Owned by client. | 411 // Holds the initialized demuxer. Used for seeking. Owned by client. |
344 Demuxer* demuxer_; | 412 Demuxer* demuxer_; |
345 | 413 |
346 // Holds the initialized renderers. Used for setting the volume, | 414 // Holds the initialized renderers. Used for setting the volume, |
347 // playback rate, and determining when playback has finished. | 415 // playback rate, and determining when playback has finished. |
348 scoped_ptr<Renderer> renderer_; | 416 scoped_ptr<AudioRenderer> audio_renderer_; |
| 417 scoped_ptr<VideoRenderer> video_renderer_; |
349 scoped_ptr<TextRenderer> text_renderer_; | 418 scoped_ptr<TextRenderer> text_renderer_; |
350 | 419 |
| 420 // Renderer-provided time source used to control playback. |
| 421 TimeSource* time_source_; |
| 422 |
351 PipelineStatistics statistics_; | 423 PipelineStatistics statistics_; |
352 | 424 |
353 scoped_ptr<SerialRunner> pending_callbacks_; | 425 scoped_ptr<SerialRunner> pending_callbacks_; |
354 | 426 |
| 427 bool underflow_disabled_for_testing_; |
| 428 |
355 base::ThreadChecker thread_checker_; | 429 base::ThreadChecker thread_checker_; |
356 | 430 |
357 // NOTE: Weak pointers must be invalidated before all other member variables. | 431 // NOTE: Weak pointers must be invalidated before all other member variables. |
358 base::WeakPtrFactory<Pipeline> weak_factory_; | 432 base::WeakPtrFactory<Pipeline> weak_factory_; |
359 | 433 |
360 DISALLOW_COPY_AND_ASSIGN(Pipeline); | 434 DISALLOW_COPY_AND_ASSIGN(Pipeline); |
361 }; | 435 }; |
362 | 436 |
363 } // namespace media | 437 } // namespace media |
364 | 438 |
365 #endif // MEDIA_BASE_PIPELINE_H_ | 439 #endif // MEDIA_BASE_PIPELINE_H_ |
OLD | NEW |