diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-08 00:21:07 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-08 00:21:07 +0000 |
commit | 8e398d50a76ebaa7d37ff62f06fc65a307718b29 (patch) | |
tree | 1eb862e295cd7b542ea14ede0cf13ec78293bd77 | |
parent | 54d6e999913dddd3c2fb4acd9522e4d8b5c35928 (diff) | |
download | chromium_src-8e398d50a76ebaa7d37ff62f06fc65a307718b29.zip chromium_src-8e398d50a76ebaa7d37ff62f06fc65a307718b29.tar.gz chromium_src-8e398d50a76ebaa7d37ff62f06fc65a307718b29.tar.bz2 |
Report errors occurring during WASAPI startup.
We see a lot of crash reports around closing invalid handles. It's
possible these are due to unreported errors that result in unstarted
threads being joined.
BUG=none
TEST=none
Review URL: https://codereview.chromium.org/26069003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227400 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | media/audio/win/audio_low_latency_output_win.cc | 62 | ||||
-rw-r--r-- | media/audio/win/audio_low_latency_output_win.h | 8 |
2 files changed, 40 insertions, 30 deletions
diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc index c889c03..e2c3ca7 100644 --- a/media/audio/win/audio_low_latency_output_win.cc +++ b/media/audio/win/audio_low_latency_output_win.cc @@ -322,14 +322,18 @@ void WASAPIAudioOutputStream::Start(AudioSourceCallback* callback) { render_thread_->Start(); if (!render_thread_->HasBeenStarted()) { LOG(ERROR) << "Failed to start WASAPI render thread."; + StopThread(); + callback->OnError(this); return; } // Ensure that the endpoint buffer is prepared with silence. if (share_mode_ == AUDCLNT_SHAREMODE_SHARED) { if (!CoreAudioUtil::FillRenderEndpointBufferWithSilence( - audio_client_, audio_render_client_)) { - LOG(WARNING) << "Failed to prepare endpoint buffers with silence."; + audio_client_, audio_render_client_)) { + LOG(ERROR) << "Failed to prepare endpoint buffers with silence."; + StopThread(); + callback->OnError(this); return; } } @@ -338,10 +342,10 @@ void WASAPIAudioOutputStream::Start(AudioSourceCallback* callback) { // Start streaming data between the endpoint buffer and the audio engine. HRESULT hr = audio_client_->Start(); if (FAILED(hr)) { - SetEvent(stop_render_event_.Get()); - render_thread_->Join(); - render_thread_.reset(); - HandleError(hr); + LOG_GETLASTERROR(ERROR) + << "Failed to start output streaming: " << std::hex << hr; + StopThread(); + callback->OnError(this); } } @@ -354,27 +358,21 @@ void WASAPIAudioOutputStream::Stop() { // Stop output audio streaming. HRESULT hr = audio_client_->Stop(); if (FAILED(hr)) { - LOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) + LOG_GETLASTERROR(ERROR) << "Failed to stop output streaming: " << std::hex << hr; + source_->OnError(this); } - // Wait until the thread completes and perform cleanup. - SetEvent(stop_render_event_.Get()); - render_thread_->Join(); - render_thread_.reset(); - - // Ensure that we don't quit the main thread loop immediately next - // time Start() is called. - ResetEvent(stop_render_event_.Get()); - - // Clear source callback, it'll be set again on the next Start() call. - source_ = NULL; + // Make a local copy of |source_| since StopThread() will clear it. + AudioSourceCallback* callback = source_; + StopThread(); // Flush all pending data and reset the audio clock stream position to 0. hr = audio_client_->Reset(); if (FAILED(hr)) { - LOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) + LOG_GETLASTERROR(ERROR) << "Failed to reset streaming: " << std::hex << hr; + callback->OnError(this); } // Extra safety check to ensure that the buffers are cleared. @@ -619,14 +617,6 @@ void WASAPIAudioOutputStream::RenderAudioFromSource( } } -void WASAPIAudioOutputStream::HandleError(HRESULT err) { - CHECK((started() && GetCurrentThreadId() == render_thread_->tid()) || - (!started() && GetCurrentThreadId() == creating_thread_id_)); - NOTREACHED() << "Error code: " << std::hex << err; - if (source_) - source_->OnError(this); -} - HRESULT WASAPIAudioOutputStream::ExclusiveModeInitialization( IAudioClient* client, HANDLE event_handle, uint32* endpoint_buffer_size) { DCHECK_EQ(share_mode_, AUDCLNT_SHAREMODE_EXCLUSIVE); @@ -706,4 +696,22 @@ HRESULT WASAPIAudioOutputStream::ExclusiveModeInitialization( return hr; } +void WASAPIAudioOutputStream::StopThread() { + if (render_thread_ ) { + if (render_thread_->HasBeenStarted()) { + // Wait until the thread completes and perform cleanup. + SetEvent(stop_render_event_.Get()); + render_thread_->Join(); + } + + render_thread_.reset(); + + // Ensure that we don't quit the main thread loop immediately next + // time Start() is called. + ResetEvent(stop_render_event_.Get()); + } + + source_ = NULL; +} + } // namespace media diff --git a/media/audio/win/audio_low_latency_output_win.h b/media/audio/win/audio_low_latency_output_win.h index 7884d88..04d5ef4 100644 --- a/media/audio/win/audio_low_latency_output_win.h +++ b/media/audio/win/audio_low_latency_output_win.h @@ -170,9 +170,6 @@ class MEDIA_EXPORT WASAPIAudioOutputStream : // glitches. void RenderAudioFromSource(IAudioClock* audio_clock, UINT64 device_frequency); - // Issues the OnError() callback to the |sink_|. - void HandleError(HRESULT err); - // Called when the device will be opened in exclusive mode and use the // application specified format. // TODO(henrika): rewrite and move to CoreAudioUtil when removing flag @@ -181,6 +178,11 @@ class MEDIA_EXPORT WASAPIAudioOutputStream : HANDLE event_handle, uint32* endpoint_buffer_size); + // If |render_thread_| is valid, sets |stop_render_event_| and blocks until + // the thread has stopped. |stop_render_event_| is reset after the call. + // |source_| is set to NULL. + void StopThread(); + // Contains the thread ID of the creating thread. base::PlatformThreadId creating_thread_id_; |