From fe6e532c876bf3ec6776f76f9542038ac9c94d68 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 5 Mar 2012 07:11:09 -0800 Subject: Use a separate backend callback to start playback of the device This allows us to properly update the ALCdevice and its resources with the new parameters before starting playback, instead of expecting the mixer to block and wait after it has begun. This also lets us avoid holding the device lock while resetting and starting the device, which helps prevent lock inversion on some backends (ie, one thread locking A then B, and another thread locking B then A), ultimately allowing certain backends to asynchronously update the ALCdevice without risk of lockup. Capture still has issues here, however. --- Alc/backends/opensl.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'Alc/backends/opensl.c') diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c index 58acc828..5ff60276 100644 --- a/Alc/backends/opensl.c +++ b/Alc/backends/opensl.c @@ -242,6 +242,10 @@ static void opensl_close_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + SLObjectItf_Destroy(data->outputMix); data->outputMix = NULL; @@ -257,16 +261,13 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; SLDataLocator_AndroidSimpleBufferQueue loc_bufq; - SLAndroidSimpleBufferQueueItf bufferQueue; SLDataLocator_OutputMix loc_outmix; SLDataFormat_PCM format_pcm; SLDataSource audioSrc; SLDataSink audioSnk; - SLPlayItf player; SLInterfaceID id; SLboolean req; SLresult result; - ALuint i; Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency; @@ -303,6 +304,10 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) audioSnk.pFormat = NULL; + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + result = SLEngineItf_CreateAudioPlayer(data->engine, &data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req); PRINTERR(result, "engine->CreateAudioPlayer"); if(SL_RESULT_SUCCESS == result) @@ -310,11 +315,29 @@ static ALCboolean opensl_reset_playback(ALCdevice *Device) result = SLObjectItf_Realize(data->bufferQueueObject, SL_BOOLEAN_FALSE); PRINTERR(result, "bufferQueue->Realize"); } - if(SL_RESULT_SUCCESS == result) + + if(SL_RESULT_SUCCESS != result) { - result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); - PRINTERR(result, "bufferQueue->GetInterface"); + if(data->bufferQueueObject != NULL) + SLObjectItf_Destroy(data->bufferQueueObject); + data->bufferQueueObject = NULL; + + return ALC_FALSE; } + + return ALC_TRUE; +} + +static ALCboolean opensl_start_playback(ALCdevice *Device) +{ + osl_data *data = Device->ExtraData; + SLAndroidSimpleBufferQueueItf bufferQueue; + SLPlayItf player; + SLresult result; + ALuint i; + + result = SLObjectItf_GetInterface(data->bufferQueueObject, SL_IID_BUFFERQUEUE, &bufferQueue); + PRINTERR(result, "bufferQueue->GetInterface"); if(SL_RESULT_SUCCESS == result) { result = (*bufferQueue)->RegisterCallback(bufferQueue, opensl_callback, Device); @@ -372,10 +395,6 @@ static void opensl_stop_playback(ALCdevice *Device) { osl_data *data = Device->ExtraData; - if(data->bufferQueueObject != NULL) - SLObjectItf_Destroy(data->bufferQueueObject); - data->bufferQueueObject = NULL; - free(data->buffer); data->buffer = NULL; data->bufferSize = 0; @@ -386,6 +405,7 @@ static const BackendFuncs opensl_funcs = { opensl_open_playback, opensl_close_playback, opensl_reset_playback, + opensl_start_playback, opensl_stop_playback, NULL, NULL, -- cgit v1.2.3