summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-08 00:21:07 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-08 00:21:07 +0000
commit8e398d50a76ebaa7d37ff62f06fc65a307718b29 (patch)
tree1eb862e295cd7b542ea14ede0cf13ec78293bd77
parent54d6e999913dddd3c2fb4acd9522e4d8b5c35928 (diff)
downloadchromium_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.cc62
-rw-r--r--media/audio/win/audio_low_latency_output_win.h8
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_;