mirror of
https://github.com/shadps4-emu/ext-SDL.git
synced 2025-02-21 19:20:41 +00:00
Pause and resume Android audio without taking device locks
The AAudio driver implemented pause/resume by dangerously locking the audio devices. If there was an audio hotplug event or a background thread tried to interact with the audio system, this could cause deadlocks.
This commit is contained in:
parent
9d35f178a6
commit
5318e30ee5
@ -43,7 +43,6 @@ struct SDL_PrivateAudioData
|
||||
size_t processed_bytes;
|
||||
SDL_Semaphore *semaphore;
|
||||
SDL_AtomicInt error_callback_triggered;
|
||||
SDL_bool resume; // Resume device if it was paused automatically
|
||||
};
|
||||
|
||||
// Debug
|
||||
@ -165,7 +164,18 @@ static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
||||
|
||||
static int AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_WaitSemaphore(device->hidden->semaphore);
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
// this semaphore won't fire when the app is in the background (AAUDIO_PauseDevices was called).
|
||||
const int rc = SDL_WaitSemaphoreTimeout(device->hidden->semaphore, 100);
|
||||
if (rc == -1) { // uh, what?
|
||||
return -1;
|
||||
} else if (rc == 0) {
|
||||
return 0; // semaphore was signaled, let's go!
|
||||
} else {
|
||||
SDL_assert(rc == SDL_MUTEX_TIMEDOUT);
|
||||
}
|
||||
// Still waiting on the semaphore (or the system), check other things then wait again.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,9 +449,6 @@ static SDL_bool PauseOneDevice(SDL_AudioDevice *device, void *userdata)
|
||||
LOGI("SDL Failed AAudioStream_requestPause %d", res);
|
||||
SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res));
|
||||
}
|
||||
|
||||
SDL_LockMutex(device->lock);
|
||||
hidden->resume = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE; // keep enumerating.
|
||||
@ -460,11 +467,6 @@ static SDL_bool ResumeOneDevice(SDL_AudioDevice *device, void *userdata)
|
||||
{
|
||||
struct SDL_PrivateAudioData *hidden = device->hidden;
|
||||
if (hidden) {
|
||||
if (hidden->resume) {
|
||||
hidden->resume = SDL_FALSE;
|
||||
SDL_UnlockMutex(device->lock);
|
||||
}
|
||||
|
||||
if (hidden->stream) {
|
||||
aaudio_result_t res = ctx.AAudioStream_requestStart(hidden->stream);
|
||||
if (res != AAUDIO_OK) {
|
||||
|
@ -23,16 +23,7 @@
|
||||
#ifndef SDL_aaudio_h_
|
||||
#define SDL_aaudio_h_
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_AAUDIO
|
||||
|
||||
void AAUDIO_ResumeDevices(void);
|
||||
void AAUDIO_PauseDevices(void);
|
||||
|
||||
#else
|
||||
|
||||
#define AAUDIO_ResumeDevices()
|
||||
#define AAUDIO_PauseDevices()
|
||||
|
||||
#endif
|
||||
extern void AAUDIO_ResumeDevices(void);
|
||||
extern void AAUDIO_PauseDevices(void);
|
||||
|
||||
#endif // SDL_aaudio_h_
|
||||
|
@ -652,8 +652,19 @@ static int OPENSLES_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
LOGV("OPENSLES_WaitDevice()");
|
||||
|
||||
// Wait for an audio chunk to finish
|
||||
return SDL_WaitSemaphore(audiodata->playsem);
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
// this semaphore won't fire when the app is in the background (OPENSLES_PauseDevices was called).
|
||||
const int rc = SDL_WaitSemaphoreTimeout(audiodata->playsem, 100);
|
||||
if (rc == -1) { // uh, what?
|
||||
return -1;
|
||||
} else if (rc == 0) {
|
||||
return 0; // semaphore was signaled, let's go!
|
||||
} else {
|
||||
SDL_assert(rc == SDL_MUTEX_TIMEDOUT);
|
||||
}
|
||||
// Still waiting on the semaphore (or the system), check other things then wait again.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int OPENSLES_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||
|
@ -23,16 +23,7 @@
|
||||
#ifndef SDL_openslesaudio_h_
|
||||
#define SDL_openslesaudio_h_
|
||||
|
||||
#ifdef SDL_AUDIO_DRIVER_OPENSLES
|
||||
|
||||
void OPENSLES_ResumeDevices(void);
|
||||
void OPENSLES_PauseDevices(void);
|
||||
|
||||
#else
|
||||
|
||||
static void OPENSLES_ResumeDevices(void) {}
|
||||
static void OPENSLES_PauseDevices(void) {}
|
||||
|
||||
#endif
|
||||
extern void OPENSLES_ResumeDevices(void);
|
||||
extern void OPENSLES_PauseDevices(void);
|
||||
|
||||
#endif // SDL_openslesaudio_h_
|
||||
|
Loading…
x
Reference in New Issue
Block a user