| Index: media/filters/renderer_impl.h
|
| diff --git a/media/filters/renderer_impl.h b/media/filters/renderer_impl.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c4bd59f49105557a51f3ca673ec84990242eb6c5
|
| --- /dev/null
|
| +++ b/media/filters/renderer_impl.h
|
| @@ -0,0 +1,200 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef MEDIA_FILTERS_RENDERER_IMPL_H_
|
| +#define MEDIA_FILTERS_RENDERER_IMPL_H_
|
| +
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "base/synchronization/lock.h"
|
| +#include "base/time/clock.h"
|
| +#include "base/time/default_tick_clock.h"
|
| +#include "base/time/time.h"
|
| +#include "media/base/buffering_state.h"
|
| +#include "media/base/media_export.h"
|
| +#include "media/base/pipeline_status.h"
|
| +#include "media/base/renderer.h"
|
| +
|
| +namespace base {
|
| +class SingleThreadTaskRunner;
|
| +}
|
| +
|
| +namespace media {
|
| +
|
| +class AudioRenderer;
|
| +class Demuxer;
|
| +class FilterCollection;
|
| +class TimeDeltaInterpolator;
|
| +class TimeSource;
|
| +class VideoRenderer;
|
| +
|
| +class MEDIA_EXPORT RendererImpl : public Renderer {
|
| + public:
|
| + typedef base::Callback<base::TimeDelta()> TimeDeltaCB;
|
| +
|
| + // Renders audio/video streams in |demuxer| using AudioRenderer and
|
| + // VideoRenderer provided in |filter_collection|. All methods except for
|
| + // GetMediaTime() run on the |task_runner|. GetMediaTime() runs on the render
|
| + // main thread because it's part of JS sync API.
|
| + // |get_duration_cb| is used to get the duration of the stream.
|
| + RendererImpl(Demuxer* demuxer,
|
| + scoped_ptr<FilterCollection> filter_collection,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| + const TimeDeltaCB& get_duration_cb);
|
| +
|
| + // Stops rendering and fires all pending callbacks.
|
| + virtual ~RendererImpl();
|
| +
|
| + // Renderer implementation.
|
| + virtual void Initialize(const PipelineStatusCB& init_cb,
|
| + const StatisticsCB& statistics_cb,
|
| + const base::Closure& ended_cb,
|
| + const PipelineStatusCB& error_cb,
|
| + const BufferingStateCB& buffering_state_cb) OVERRIDE;
|
| + virtual void Flush(const base::Closure& flush_cb) OVERRIDE;
|
| + virtual void StartPlayingFrom(base::TimeDelta timestamp) OVERRIDE;
|
| + virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
|
| + virtual void SetVolume(float volume) OVERRIDE;
|
| + virtual base::TimeDelta GetMediaTime() const OVERRIDE;
|
| + virtual bool HasAudio() const OVERRIDE;
|
| + virtual bool HasVideo() const OVERRIDE;
|
| + virtual void SetCdm(MediaKeys* cdm) OVERRIDE;
|
| + virtual void DisableUnderflowForTesting() OVERRIDE;
|
| + virtual void SetTimeDeltaInterpolatorForTesting(
|
| + TimeDeltaInterpolator* interpolator) OVERRIDE;
|
| +
|
| + private:
|
| + enum State {
|
| + kUninitialized,
|
| + kInitializing,
|
| + kFlushing,
|
| + kPlaying,
|
| + kError
|
| + };
|
| +
|
| + base::TimeDelta GetMediaDuration();
|
| +
|
| + // Helper functions and callbacks for Initialize().
|
| + void InitializeAudioRenderer();
|
| + void OnAudioRendererInitializeDone(PipelineStatus status);
|
| + void InitializeVideoRenderer();
|
| + void OnVideoRendererInitializeDone(PipelineStatus status);
|
| +
|
| + // Helper functions and callbacks for Flush().
|
| + void FlushAudioRenderer();
|
| + void OnAudioRendererFlushDone();
|
| + void FlushVideoRenderer();
|
| + void OnVideoRendererFlushDone();
|
| +
|
| + // Callback executed by audio renderer to update clock time.
|
| + void OnAudioTimeUpdate(base::TimeDelta time, base::TimeDelta max_time);
|
| +
|
| + // Callback executed by video renderer to update clock time.
|
| + void OnVideoTimeUpdate(base::TimeDelta max_time);
|
| +
|
| + // Callback executed by filters to update statistics.
|
| + void OnUpdateStatistics(const PipelineStatistics& stats);
|
| +
|
| + // Collection of callback methods and helpers for tracking changes in
|
| + // buffering state and transition from paused/underflow states and playing
|
| + // states.
|
| + //
|
| + // While in the kPlaying state:
|
| + // - A waiting to non-waiting transition indicates preroll has completed
|
| + // and StartPlayback() should be called
|
| + // - A non-waiting to waiting transition indicates underflow has occurred
|
| + // and PausePlayback() should be called
|
| + void OnBufferingStateChanged(BufferingState* buffering_state,
|
| + BufferingState new_buffering_state);
|
| + bool WaitingForEnoughData() const;
|
| + void PausePlayback();
|
| + void StartPlayback();
|
| +
|
| + void PauseClockAndStopTicking_Locked();
|
| + void StartClockIfWaitingForTimeUpdate_Locked();
|
| +
|
| + // Callbacks executed when a renderer has ended.
|
| + void OnAudioRendererEnded();
|
| + void OnVideoRendererEnded();
|
| + void RunEndedCallbackIfNeeded();
|
| +
|
| + // Callback executed when a runtime error happens.
|
| + void OnError(PipelineStatus error);
|
| +
|
| + State state_;
|
| +
|
| + // Task runner used to execute pipeline tasks.
|
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
|
| +
|
| + scoped_ptr<FilterCollection> filter_collection_;
|
| + Demuxer* demuxer_;
|
| +
|
| + // Permanent callback to get the media duration.
|
| + TimeDeltaCB get_duration_cb_;
|
| +
|
| + // Permanent callbacks to notify various renderer states/stats.
|
| + StatisticsCB statistics_cb_;
|
| + base::Closure ended_cb_;
|
| + PipelineStatusCB error_cb_;
|
| + BufferingStateCB buffering_state_cb_;
|
| +
|
| + // Temporary callback used for Initialize() and Flush().
|
| + PipelineStatusCB init_cb_;
|
| + base::Closure flush_cb_;
|
| +
|
| + scoped_ptr<AudioRenderer> audio_renderer_;
|
| + scoped_ptr<VideoRenderer> video_renderer_;
|
| +
|
| + // Renderer-provided time source used to control playback.
|
| + TimeSource* time_source_;
|
| +
|
| + // The timestamp to start playback from after starting/seeking has completed.
|
| + base::TimeDelta start_timestamp_;
|
| +
|
| + BufferingState audio_buffering_state_;
|
| + BufferingState video_buffering_state_;
|
| +
|
| + // Whether we've received the audio/video ended events.
|
| + bool audio_ended_;
|
| + bool video_ended_;
|
| +
|
| + bool underflow_disabled_for_testing_;
|
| +
|
| + // Protects time interpolation related member variables, i.e. |interpolator_|,
|
| + // |default_tick_clock_| and |interpolation_state_|. This is because
|
| + // |interpolator_| can be used on different threads (see GetMediaTime()).
|
| + mutable base::Lock interpolator_lock_;
|
| +
|
| + // Tracks the most recent media time update and provides interpolated values
|
| + // as playback progresses.
|
| + scoped_ptr<TimeDeltaInterpolator> interpolator_;
|
| +
|
| + // base::TickClock used by |interpolator_|.
|
| + // TODO(xhwang): This can be TimeDeltaInterpolator's implementation detail.
|
| + base::DefaultTickClock default_tick_clock_;
|
| +
|
| + enum InterpolationState {
|
| + // Audio (if present) is not rendering. Time isn't being interpolated.
|
| + INTERPOLATION_STOPPED,
|
| +
|
| + // Audio (if present) is rendering. Time isn't being interpolated.
|
| + INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE,
|
| +
|
| + // Audio (if present) is rendering. Time is being interpolated.
|
| + INTERPOLATION_STARTED,
|
| + };
|
| +
|
| + InterpolationState interpolation_state_;
|
| +
|
| + // NOTE: Weak pointers must be invalidated before all other member variables.
|
| + base::WeakPtrFactory<RendererImpl> weak_factory_;
|
| + base::WeakPtr<RendererImpl> weak_this_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RendererImpl);
|
| +};
|
| +
|
| +} // namespace media
|
| +
|
| +#endif // MEDIA_FILTERS_RENDERER_IMPL_H_
|
|
|