Bug 1131768 - Unlock before tearing down the stream in case of error, to avoid recursive locking. r=kinetik, a=sledru
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -929,37 +929,40 @@ int setup_wasapi_stream(cubeb_stream * s
auto_com com;
assert(!stm->client && "WASAPI stream already setup, close it first.");
hr = get_default_endpoint(&device);
if (FAILED(hr)) {
LOG("Could not get default endpoint, error: %x", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
/* Get a client. We will get all other interfaces we need from
* this pointer. */
hr = device->Activate(__uuidof(IAudioClient),
CLSCTX_INPROC_SERVER,
NULL, (void **)&stm->client);
SafeRelease(device);
if (FAILED(hr)) {
LOG("Could not activate the device to get an audio client: error: %x", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
/* We have to distinguish between the format the mixer uses,
* and the format the stream we want to play uses. */
hr = stm->client->GetMixFormat(&mix_format);
if (FAILED(hr)) {
LOG("Could not fetch current mix format from the audio client: error: %x", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
handle_channel_layout(stm, &mix_format, &stm->stream_params);
/* Shared mode WASAPI always supports float32 sample format, so this
* is safe. */
@@ -974,65 +977,71 @@ int setup_wasapi_stream(cubeb_stream * s
0,
mix_format,
NULL);
CoTaskMemFree(mix_format);
if (FAILED(hr)) {
LOG("Unable to initialize audio client: %x.", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
hr = stm->client->GetBufferSize(&stm->buffer_frame_count);
if (FAILED(hr)) {
LOG("Could not get the buffer size from the client %x.", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
if (should_upmix(stm) || should_downmix(stm)) {
stm->mix_buffer = (float *)malloc(frames_to_bytes_before_mix(stm, stm->buffer_frame_count));
}
hr = stm->client->SetEventHandle(stm->refill_event);
if (FAILED(hr)) {
LOG("Could set the event handle for the client %x.", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
hr = stm->client->GetService(__uuidof(IAudioRenderClient),
(void **)&stm->render_client);
if (FAILED(hr)) {
LOG("Could not get the render client %x.", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
hr = stm->client->GetService(__uuidof(IAudioStreamVolume),
(void **)&stm->audio_stream_volume);
if (FAILED(hr)) {
LOG("Could not get the IAudioStreamVolume %x.", hr);
+ auto_unlock unlock(stm->stream_reset_lock);
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
/* If we are playing a mono stream, we only resample one channel,
* and copy it over, so we are always resampling the number
* of channels of the stream, not the number of channels
* that WASAPI wants. */
stm->resampler = cubeb_resampler_create(stm, stm->stream_params,
stm->mix_params.rate,
stm->data_callback,
stm->buffer_frame_count,
stm->user_ptr,
CUBEB_RESAMPLER_QUALITY_DESKTOP);
if (!stm->resampler) {
+ auto_unlock unlock(stm->stream_reset_lock);
LOG("Could not get a resampler");
wasapi_stream_destroy(stm);
return CUBEB_ERROR;
}
return CUBEB_OK;
}