Chromium Code Reviews| Index: media/blink/webaudiosourceprovider_impl.cc |
| diff --git a/media/blink/webaudiosourceprovider_impl.cc b/media/blink/webaudiosourceprovider_impl.cc |
| index 3f052dbeb6f5a8f9759964cb534635f5e19ebd79..b2b04e834c8c19f76d38ea48280cab498664cf69 100644 |
| --- a/media/blink/webaudiosourceprovider_impl.cc |
| +++ b/media/blink/webaudiosourceprovider_impl.cc |
| @@ -50,18 +50,22 @@ class AutoTryLock { |
| // TeeFilter is a RenderCallback implementation that allows for a client to get |
| // a copy of the data being rendered by the |renderer_| on Render(). This class |
| -// also holds to the necessary audio parameters. |
| +// also holds on to the necessary audio parameters. |
| class WebAudioSourceProviderImpl::TeeFilter |
| : public AudioRendererSink::RenderCallback { |
| public: |
| - TeeFilter(AudioRendererSink::RenderCallback* renderer, |
| - int channels, |
| - int sample_rate) |
| - : renderer_(renderer), channels_(channels), sample_rate_(sample_rate) { |
| - DCHECK(renderer_); |
| - } |
| + TeeFilter() : renderer_(nullptr), channels_(0), sample_rate_(0) {} |
| ~TeeFilter() override {} |
| + void Initialize(AudioRendererSink::RenderCallback* renderer, |
| + int channels, |
| + int sample_rate) { |
| + DCHECK(renderer); |
| + renderer_ = renderer; |
| + channels_ = channels; |
| + sample_rate_ = sample_rate; |
| + } |
| + |
| // AudioRendererSink::RenderCallback implementation. |
| // These are forwarders to |renderer_| and are here to allow for a client to |
| // get a copy of the rendered audio by SetCopyAudioCallback(). |
| @@ -70,19 +74,19 @@ class WebAudioSourceProviderImpl::TeeFilter |
| uint32_t frames_skipped) override; |
| void OnRenderError() override; |
| + bool IsInitialized() const { return !!renderer_; } |
| int channels() const { return channels_; } |
| int sample_rate() const { return sample_rate_; } |
| - void set_copy_audio_bus_callback( |
| - const WebAudioSourceProviderImpl::CopyAudioCB& callback) { |
| + void set_copy_audio_bus_callback(const CopyAudioCB& callback) { |
| copy_audio_bus_callback_ = callback; |
| } |
| private: |
| - AudioRendererSink::RenderCallback* const renderer_; |
| - const int channels_; |
| - const int sample_rate_; |
| + AudioRendererSink::RenderCallback* renderer_; |
| + int channels_; |
| + int sample_rate_; |
| - WebAudioSourceProviderImpl::CopyAudioCB copy_audio_bus_callback_; |
| + CopyAudioCB copy_audio_bus_callback_; |
| DISALLOW_COPY_AND_ASSIGN(TeeFilter); |
| }; |
| @@ -93,6 +97,7 @@ WebAudioSourceProviderImpl::WebAudioSourceProviderImpl( |
| state_(kStopped), |
| client_(nullptr), |
| sink_(sink), |
| + tee_filter_(new TeeFilter()), |
| weak_factory_(this) {} |
| WebAudioSourceProviderImpl::~WebAudioSourceProviderImpl() { |
| @@ -111,12 +116,11 @@ void WebAudioSourceProviderImpl::setClient( |
| set_format_cb_ = BindToCurrentLoop(base::Bind( |
| &WebAudioSourceProviderImpl::OnSetFormat, weak_factory_.GetWeakPtr())); |
| - // If |tee_filter_| is set, it means we have been Initialize()d - then run |
| - // |set_format_cb_| to send |client_| the current format info. Otherwise |
| - // |set_format_cb_| will get called when Initialize() is called. |
| - // Note: Always using |set_format_cb_| ensures we have the same locking |
| - // order when calling into |client_|. |
| - if (tee_filter_) |
| + // If |tee_filter_| is Initialize()d - then run |set_format_cb_| to send |
| + // |client_| the current format info. Otherwise |set_format_cb_| will get |
| + // called when Initialize() is called. Note: Always using |set_format_cb_| |
| + // ensures we have the same locking order when calling into |client_|. |
| + if (tee_filter_->IsInitialized()) // ??? |
|
DaleCurtis
2016/05/23 18:37:18
Remove ???
mcasas
2016/05/23 19:00:13
Done.
|
| base::ResetAndReturn(&set_format_cb_).Run(); |
| } else if (!client && client_) { |
| // Restore normal playback. |
| @@ -151,7 +155,6 @@ void WebAudioSourceProviderImpl::provideInput( |
| } |
| DCHECK(client_); |
| - DCHECK(tee_filter_); |
| DCHECK_EQ(tee_filter_->channels(), bus_wrapper_->channels()); |
| const int frames = tee_filter_->Render(bus_wrapper_.get(), 0, 0); |
| if (frames < incoming_number_of_frames) |
| @@ -221,8 +224,7 @@ void WebAudioSourceProviderImpl::Initialize(const AudioParameters& params, |
| base::AutoLock auto_lock(sink_lock_); |
| DCHECK_EQ(state_, kStopped); |
| - tee_filter_ = base::WrapUnique( |
| - new TeeFilter(renderer, params.channels(), params.sample_rate())); |
| + tee_filter_->Initialize(renderer, params.channels(), params.sample_rate()); |
| sink_->Initialize(params, tee_filter_.get()); |
| @@ -233,6 +235,10 @@ void WebAudioSourceProviderImpl::Initialize(const AudioParameters& params, |
| void WebAudioSourceProviderImpl::SetCopyAudioCallback( |
| const CopyAudioCB& callback) { |
| DCHECK(!callback.is_null()); |
| + |
| + // Use |sink_lock_| to protect |tee_filter_| too since they go in lockstep. |
| + base::AutoLock auto_lock(sink_lock_); |
| + |
| DCHECK(tee_filter_); |
| tee_filter_->set_copy_audio_bus_callback(callback); |
| } |
| @@ -242,6 +248,10 @@ void WebAudioSourceProviderImpl::ClearCopyAudioCallback() { |
| tee_filter_->set_copy_audio_bus_callback(CopyAudioCB()); |
| } |
| +int WebAudioSourceProviderImpl::RenderForTesting(AudioBus* audio_bus) { |
| + return tee_filter_->Render(audio_bus, 0, 0); |
| +} |
| + |
| void WebAudioSourceProviderImpl::OnSetFormat() { |
| base::AutoLock auto_lock(sink_lock_); |
| if (!client_) |
| @@ -251,13 +261,12 @@ void WebAudioSourceProviderImpl::OnSetFormat() { |
| client_->setFormat(tee_filter_->channels(), tee_filter_->sample_rate()); |
| } |
| -int WebAudioSourceProviderImpl::RenderForTesting(AudioBus* audio_bus) { |
| - return tee_filter_->Render(audio_bus, 0, 0); |
| -} |
| - |
| int WebAudioSourceProviderImpl::TeeFilter::Render(AudioBus* audio_bus, |
| uint32_t delay_milliseconds, |
| uint32_t frames_skipped) { |
| + if (!renderer_) |
|
DaleCurtis
2016/05/23 18:37:18
This should be impossible, no?
mcasas
2016/05/23 19:00:13
It could be possible if we get data before the
|re
|
| + return 0; |
| + |
| const int num_rendered_frames = |
| renderer_->Render(audio_bus, delay_milliseconds, frames_skipped); |
| @@ -273,7 +282,8 @@ int WebAudioSourceProviderImpl::TeeFilter::Render(AudioBus* audio_bus, |
| } |
| void WebAudioSourceProviderImpl::TeeFilter::OnRenderError() { |
| - renderer_->OnRenderError(); |
| + if (renderer_) |
|
DaleCurtis
2016/05/23 18:37:18
Ditto.
mcasas
2016/05/23 19:00:13
Acknowledged.
|
| + renderer_->OnRenderError(); |
| } |
| } // namespace media |