diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 21:01:09 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 21:01:09 +0000 |
commit | d3cb9d234027fdf031a5bc8634469d0103598260 (patch) | |
tree | 6c09ceb3680677919007ac89d99eb0edd5966e2e /media | |
parent | d685c565b865c157275a53800978cce8d40009bc (diff) | |
download | chromium_src-d3cb9d234027fdf031a5bc8634469d0103598260.zip chromium_src-d3cb9d234027fdf031a5bc8634469d0103598260.tar.gz chromium_src-d3cb9d234027fdf031a5bc8634469d0103598260.tar.bz2 |
Revert "Attempt to fix audio wedges by restarting all streams on OSX."
This reverts commit http://crrev.com/238501 in favor a simpler approach
which delays stream creation around suspend and resume events:
http://crrev.com/247026
Care must be taken to monitor the UMA stat for increases after this lands.
I'll also communicate with the YT team on the bug/ to ensure they provide
some assistance in testing.
BUG=160920
TEST=No stream hangs.
Review URL: https://codereview.chromium.org/190553004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@263076 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/audio/audio_manager.h | 5 | ||||
-rw-r--r-- | media/audio/audio_manager_base.cc | 28 | ||||
-rw-r--r-- | media/audio/audio_manager_base.h | 2 | ||||
-rw-r--r-- | media/audio/audio_output_controller.cc | 11 | ||||
-rw-r--r-- | media/audio/audio_output_dispatcher.h | 7 | ||||
-rw-r--r-- | media/audio/audio_output_dispatcher_impl.cc | 13 | ||||
-rw-r--r-- | media/audio/audio_output_dispatcher_impl.h | 3 | ||||
-rw-r--r-- | media/audio/audio_output_proxy_unittest.cc | 71 | ||||
-rw-r--r-- | media/audio/audio_output_resampler.cc | 31 | ||||
-rw-r--r-- | media/audio/audio_output_resampler.h | 2 | ||||
-rw-r--r-- | media/audio/mock_audio_manager.cc | 2 | ||||
-rw-r--r-- | media/audio/mock_audio_manager.h | 2 |
12 files changed, 2 insertions, 175 deletions
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h index a15dab5..ca38570 100644 --- a/media/audio/audio_manager.h +++ b/media/audio/audio_manager.h @@ -176,11 +176,6 @@ class MEDIA_EXPORT AudioManager { virtual scoped_ptr<AudioLog> CreateAudioLog( AudioLogFactory::AudioComponent component) = 0; - // Called when a component has detected a OS level audio wedge. Shuts down - // all active audio streams and then restarts them transparently. See - // http://crbug.com/160920 - virtual void FixWedgedAudio() = 0; - protected: AudioManager(); diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc index eab950d..60f6d23 100644 --- a/media/audio/audio_manager_base.cc +++ b/media/audio/audio_manager_base.cc @@ -400,32 +400,4 @@ scoped_ptr<AudioLog> AudioManagerBase::CreateAudioLog( return audio_log_factory_->CreateAudioLog(component); } -void AudioManagerBase::FixWedgedAudio() { - DCHECK(task_runner_->BelongsToCurrentThread()); -#if defined(OS_MACOSX) - // Through trial and error, we've found that one way to restore audio after a - // hang is to close all outstanding audio streams. Once all streams have been - // closed, new streams appear to work correctly. - // - // In Chrome terms, this means we need to ask all AudioOutputDispatchers to - // close all Open()'d streams. Once all streams across all dispatchers have - // been closed, we ask for all previously Start()'d streams to be recreated - // using the same AudioSourceCallback they had before. - // - // Since this operation takes place on the audio thread we can be sure that no - // other state-changing stream operations will take place while the fix is in - // progress. - // - // See http://crbug.com/160920 for additional details. - for (AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); - it != output_dispatchers_.end(); ++it) { - (*it)->dispatcher->CloseStreamsForWedgeFix(); - } - for (AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); - it != output_dispatchers_.end(); ++it) { - (*it)->dispatcher->RestartStreamsForWedgeFix(); - } -#endif -} - } // namespace media diff --git a/media/audio/audio_manager_base.h b/media/audio/audio_manager_base.h index 4c088fb..237eaee 100644 --- a/media/audio/audio_manager_base.h +++ b/media/audio/audio_manager_base.h @@ -115,8 +115,6 @@ class MEDIA_EXPORT AudioManagerBase : public AudioManager { virtual scoped_ptr<AudioLog> CreateAudioLog( AudioLogFactory::AudioComponent component) OVERRIDE; - virtual void FixWedgedAudio() OVERRIDE; - protected: AudioManagerBase(AudioLogFactory* audio_log_factory); diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 6d30f4b..4dafadc 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc @@ -435,15 +435,8 @@ void AudioOutputController::WedgeCheck() { // If we should be playing and we haven't, that's a wedge. if (state_ == kPlaying) { - const bool playback_success = - base::AtomicRefCountIsOne(&on_more_io_data_called_); - - UMA_HISTOGRAM_BOOLEAN( - "Media.AudioOutputControllerPlaybackStartupSuccess", playback_success); - - // Let the AudioManager try and fix it. - if (!playback_success) - audio_manager_->FixWedgedAudio(); + UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", + base::AtomicRefCountIsOne(&on_more_io_data_called_)); } } diff --git a/media/audio/audio_output_dispatcher.h b/media/audio/audio_output_dispatcher.h index d070b6b..079cba0 100644 --- a/media/audio/audio_output_dispatcher.h +++ b/media/audio/audio_output_dispatcher.h @@ -65,13 +65,6 @@ class MEDIA_EXPORT AudioOutputDispatcher // Called on the audio thread when the AudioManager is shutting down. virtual void Shutdown() = 0; - // Called by the AudioManager to restart streams when a wedge is detected. A - // wedge means the OS failed to request any audio after StartStream(). When a - // wedge is detected all streams across all dispatchers must be closed. After - // all streams are closed, streams are restarted. See http://crbug.com/160920 - virtual void CloseStreamsForWedgeFix() = 0; - virtual void RestartStreamsForWedgeFix() = 0; - const std::string& device_id() const { return device_id_; } protected: diff --git a/media/audio/audio_output_dispatcher_impl.cc b/media/audio/audio_output_dispatcher_impl.cc index 4989900..0cb3db8 100644 --- a/media/audio/audio_output_dispatcher_impl.cc +++ b/media/audio/audio_output_dispatcher_impl.cc @@ -172,17 +172,4 @@ void AudioOutputDispatcherImpl::CloseIdleStreams(size_t keep_alive) { idle_streams_.erase(idle_streams_.begin() + keep_alive, idle_streams_.end()); } -void AudioOutputDispatcherImpl::CloseStreamsForWedgeFix() { - DCHECK(task_runner_->BelongsToCurrentThread()); - CloseAllIdleStreams(); -} - -void AudioOutputDispatcherImpl::RestartStreamsForWedgeFix() { - DCHECK(task_runner_->BelongsToCurrentThread()); - - // Should only be called when the dispatcher is used with fake streams which - // don't need to be shutdown or restarted. - CHECK_EQ(params_.format(), AudioParameters::AUDIO_FAKE); -} - } // namespace media diff --git a/media/audio/audio_output_dispatcher_impl.h b/media/audio/audio_output_dispatcher_impl.h index cb1ddb9..52d647a 100644 --- a/media/audio/audio_output_dispatcher_impl.h +++ b/media/audio/audio_output_dispatcher_impl.h @@ -61,9 +61,6 @@ class MEDIA_EXPORT AudioOutputDispatcherImpl : public AudioOutputDispatcher { virtual void Shutdown() OVERRIDE; - virtual void CloseStreamsForWedgeFix() OVERRIDE; - virtual void RestartStreamsForWedgeFix() OVERRIDE; - private: friend class base::RefCountedThreadSafe<AudioOutputDispatcherImpl>; virtual ~AudioOutputDispatcherImpl(); diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc index 534a6d9..b4afe5a 100644 --- a/media/audio/audio_output_proxy_unittest.cc +++ b/media/audio/audio_output_proxy_unittest.cc @@ -673,75 +673,4 @@ TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { EXPECT_TRUE(stream2.start_called()); } -// Ensures the methods used to fix audio output wedges are working correctly. -TEST_F(AudioOutputResamplerTest, WedgeFix) { - MockAudioOutputStream stream1(&manager_, params_); - MockAudioOutputStream stream2(&manager_, params_); - MockAudioOutputStream stream3(&manager_, params_); - - // Setup the mock such that all three streams are successfully created. - EXPECT_CALL(manager(), MakeAudioOutputStream(_, _)) - .WillOnce(Return(&stream1)) - .WillOnce(Return(&stream2)) - .WillOnce(Return(&stream3)); - - // Stream1 should be able to successfully open and start. - EXPECT_CALL(stream1, Open()) - .WillOnce(Return(true)); - EXPECT_CALL(stream1, SetVolume(_)); - EXPECT_CALL(stream2, Open()) - .WillOnce(Return(true)); - EXPECT_CALL(stream2, SetVolume(_)); - - // Open and start the first proxy and stream. - AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get()); - EXPECT_TRUE(proxy1->Open()); - proxy1->Start(&callback_); - OnStart(); - - // Open, but do not start the second proxy. - AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get()); - EXPECT_TRUE(proxy2->Open()); - - // Open, start and then stop the third proxy. - AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get()); - EXPECT_TRUE(proxy3->Open()); - proxy3->Start(&callback_); - OnStart(); - proxy3->Stop(); - - // Wait for stream to timeout and shutdown. - WaitForCloseTimer(&stream2); - - EXPECT_CALL(stream1, Close()); - resampler_->CloseStreamsForWedgeFix(); - - // Don't pump the MessageLoop between CloseStreamsForWedgeFix() and - // RestartStreamsForWedgeFix() to simulate intended usage. The OnStart() call - // will take care of necessary work. - - // Stream3 should take Stream1's place after RestartStreamsForWedgeFix(). No - // additional streams should be opened for proxy2 and proxy3. - EXPECT_CALL(stream3, Open()) - .WillOnce(Return(true)); - EXPECT_CALL(stream3, SetVolume(_)); - - resampler_->RestartStreamsForWedgeFix(); - OnStart(); - - // Perform the required Stop()/Close() shutdown dance for each proxy. - proxy3->Close(); - proxy2->Close(); - proxy1->Stop(); - CloseAndWaitForCloseTimer(proxy1, &stream3); - - // Wait for all of the messages to fly and then verify stream behavior. - EXPECT_TRUE(stream1.stop_called()); - EXPECT_TRUE(stream1.start_called()); - EXPECT_TRUE(stream2.stop_called()); - EXPECT_TRUE(stream2.start_called()); - EXPECT_TRUE(stream3.stop_called()); - EXPECT_TRUE(stream3.start_called()); -} - } // namespace media diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 376b113..4863351 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc @@ -298,37 +298,6 @@ void AudioOutputResampler::Shutdown() { DCHECK(callbacks_.empty()); } -void AudioOutputResampler::CloseStreamsForWedgeFix() { - DCHECK(task_runner_->BelongsToCurrentThread()); - - // Stop and close all active streams. Once all streams across all dispatchers - // have been closed the AudioManager will call RestartStreamsForWedgeFix(). - for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); - ++it) { - if (it->second->started()) - dispatcher_->StopStream(it->first); - dispatcher_->CloseStream(it->first); - } - - // Close all idle streams as well. - dispatcher_->CloseStreamsForWedgeFix(); -} - -void AudioOutputResampler::RestartStreamsForWedgeFix() { - DCHECK(task_runner_->BelongsToCurrentThread()); - // By opening all streams first and then starting them one by one we ensure - // the dispatcher only opens streams for those which will actually be used. - for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); - ++it) { - dispatcher_->OpenStream(); - } - for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); - ++it) { - if (it->second->started()) - dispatcher_->StartStream(it->second, it->first); - } -} - OnMoreDataConverter::OnMoreDataConverter(const AudioParameters& input_params, const AudioParameters& output_params) : io_ratio_(static_cast<double>(input_params.GetBytesPerSecond()) / diff --git a/media/audio/audio_output_resampler.h b/media/audio/audio_output_resampler.h index 80c9d77..fa488aa 100644 --- a/media/audio/audio_output_resampler.h +++ b/media/audio/audio_output_resampler.h @@ -52,8 +52,6 @@ class MEDIA_EXPORT AudioOutputResampler : public AudioOutputDispatcher { double volume) OVERRIDE; virtual void CloseStream(AudioOutputProxy* stream_proxy) OVERRIDE; virtual void Shutdown() OVERRIDE; - virtual void CloseStreamsForWedgeFix() OVERRIDE; - virtual void RestartStreamsForWedgeFix() OVERRIDE; private: friend class base::RefCountedThreadSafe<AudioOutputResampler>; diff --git a/media/audio/mock_audio_manager.cc b/media/audio/mock_audio_manager.cc index 318bf09..e774b8c 100644 --- a/media/audio/mock_audio_manager.cc +++ b/media/audio/mock_audio_manager.cc @@ -107,6 +107,4 @@ scoped_ptr<AudioLog> MockAudioManager::CreateAudioLog( return scoped_ptr<AudioLog>(); } -void MockAudioManager::FixWedgedAudio() {} - } // namespace media. diff --git a/media/audio/mock_audio_manager.h b/media/audio/mock_audio_manager.h index 8ca4009..520205d 100644 --- a/media/audio/mock_audio_manager.h +++ b/media/audio/mock_audio_manager.h @@ -70,8 +70,6 @@ class MockAudioManager : public media::AudioManager { virtual scoped_ptr<AudioLog> CreateAudioLog( AudioLogFactory::AudioComponent component) OVERRIDE; - virtual void FixWedgedAudio() OVERRIDE; - protected: virtual ~MockAudioManager(); |