| Index: content/renderer/media/audio_renderer_impl.h
|
| ===================================================================
|
| --- content/renderer/media/audio_renderer_impl.h (revision 122285)
|
| +++ content/renderer/media/audio_renderer_impl.h (working copy)
|
| @@ -19,9 +19,14 @@
|
|
|
| #include <vector>
|
|
|
| +#include "base/callback.h"
|
| +#include "base/cancelable_callback.h"
|
| #include "base/gtest_prod_util.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "base/message_loop_proxy.h"
|
| #include "base/synchronization/lock.h"
|
| +#include "base/time.h"
|
| #include "content/renderer/media/audio_device.h"
|
| #include "media/audio/audio_io.h"
|
| #include "media/audio/audio_parameters.h"
|
| @@ -32,6 +37,7 @@
|
|
|
| class CONTENT_EXPORT AudioRendererImpl
|
| : public media::AudioRendererBase,
|
| + NON_EXPORTED_BASE(public base::SupportsWeakPtr<AudioRendererImpl>),
|
| NON_EXPORTED_BASE(public media::AudioRendererSink::RenderCallback) {
|
| public:
|
| // Methods called on Render thread ------------------------------------------
|
| @@ -67,6 +73,17 @@
|
| FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest,
|
| DestroyedMessageLoop_ConsumeAudioSamples);
|
| FRIEND_TEST_ALL_PREFIXES(AudioRendererImplTest, UpdateEarliestEndTime);
|
| +
|
| + enum state { NOT_PLAYING, PLAYING, ENDED_EVENT_SCHEDULED, STOPPED };
|
| +
|
| + // Thread-safe accessor. Not necessary on all current platforms,
|
| + // state can be set to STOPPED only on the pipeline thread,
|
| + // but better to have it safe for the future.
|
| + bool stopped() {
|
| + base::AutoLock auto_lock(audio_renderer_impl_lock_);
|
| + return (state_ == STOPPED);
|
| + }
|
| +
|
| // Helper methods.
|
| // Convert number of bytes to duration of time using information about the
|
| // number of channels, sample rate and sample bits.
|
| @@ -76,6 +93,12 @@
|
| void DoPlay();
|
| void DoPause();
|
| void DoSeek();
|
| + void DoSignalEndOfStream();
|
| + // We cannot set pipeline message loop in the constructor/initializer because
|
| + // message loop is not created at that moment. So set it after it is created,
|
| + // in the DoPlay(). Also DCHECK() that all functions we are expecting to be
|
| + // called from the pipeline message loop are actually called from it.
|
| + void DoSetOrCheckMessageLoopProxy();
|
|
|
| // media::AudioRendererSink::RenderCallback implementation.
|
| virtual size_t Render(const std::vector<float*>& audio_data,
|
| @@ -83,8 +106,20 @@
|
| size_t audio_delay_milliseconds) OVERRIDE;
|
| virtual void OnRenderError() OVERRIDE;
|
|
|
| + // Returns current message loop proxy.
|
| + // Made virtual so test can override -- tests use
|
| + // ChildProcess::current()->io_message_loop_proxy() instead of
|
| + // MessageLoop::current()->message_loop_proxy().
|
| + virtual base::MessageLoopProxy* current_message_loop_proxy() {
|
| + return MessageLoop::current()->message_loop_proxy();
|
| + }
|
| +
|
| + // Returns delay in ms before call to OnRenderEndOfStream().
|
| + // Made virtual so test can override.
|
| + virtual int64 OnRenderEndOfStreamDelay();
|
| +
|
| // Accessors used by tests.
|
| - base::Time earliest_end_time() const {
|
| + base::Time earliest_end_time() {
|
| return earliest_end_time_;
|
| }
|
|
|
| @@ -101,11 +136,14 @@
|
| base::TimeDelta request_delay,
|
| base::Time time_now);
|
|
|
| + // Lock protecting data that can be accessed form pipeline and audio threads.
|
| + base::Lock audio_renderer_impl_lock_;
|
| +
|
| // Used to calculate audio delay given bytes.
|
| uint32 bytes_per_second_;
|
|
|
| - // A flag that indicates this filter is called to stop.
|
| - bool stopped_;
|
| + // Current state.
|
| + state state_;
|
|
|
| // The sink (destination) for rendered audio.
|
| scoped_refptr<media::AudioRendererSink> sink_;
|
| @@ -127,10 +165,22 @@
|
| // empty till that time. Workaround is not bulletproof, as we don't exactly
|
| // know when that particular data would start playing, but it is much better
|
| // than nothing.
|
| + // Access should be protected by lock as it can be accessed by pipeline and
|
| + // audio threads.
|
| base::Time earliest_end_time_;
|
|
|
| AudioParameters audio_parameters_;
|
|
|
| + // Use message loop proxy, not message loop itself, to avoid crash
|
| + // because of message loop that ended while we are still playing.
|
| + // We don't need complex shutdown operations, just not posting tasks
|
| + // is enough, so we can use message loop proxy.
|
| + scoped_refptr<base::MessageLoopProxy> pipeline_message_loop_proxy_;
|
| +
|
| + // Cancellable closure called on end of stream.
|
| + // We may schedule the task but later cancel it on seek / pause.
|
| + base::CancelableClosure signal_end_of_stream_callback_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
|
| };
|
|
|
|
|