sdl audio: fix crash when decrasing audio buffer size. fix deadlock
sample_count wasn't reset to 0 on init, so it could point past the end of the audio buffer if buffer size is decreased, leading to a crash. Fix for MINIDUMP-29 Deadlock if audio buffer size is too small (< 1024 samples)
This commit is contained in:
parent
2b37a5dc08
commit
1e195b7237
|
@ -14,6 +14,7 @@ class SDLAudioBackend : AudioBackend
|
||||||
cResetEvent read_wait;
|
cResetEvent read_wait;
|
||||||
std::mutex stream_mutex;
|
std::mutex stream_mutex;
|
||||||
uint32_t *sample_buffer;
|
uint32_t *sample_buffer;
|
||||||
|
unsigned sample_buffer_size = 0;
|
||||||
unsigned sample_count = 0;
|
unsigned sample_count = 0;
|
||||||
SDL_AudioCVT audioCvt;
|
SDL_AudioCVT audioCvt;
|
||||||
|
|
||||||
|
@ -75,7 +76,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_buffer = new uint32_t[config::AudioBufferSize]();
|
sample_buffer_size = std::max<u32>(SAMPLE_COUNT * 2, config::AudioBufferSize);
|
||||||
|
sample_buffer = new uint32_t[sample_buffer_size]();
|
||||||
|
sample_count = 0;
|
||||||
|
|
||||||
// Support 44.1KHz (native) but also upsampling to 48KHz
|
// Support 44.1KHz (native) but also upsampling to 48KHz
|
||||||
SDL_AudioSpec wav_spec, out_spec;
|
SDL_AudioSpec wav_spec, out_spec;
|
||||||
|
@ -86,6 +89,7 @@ public:
|
||||||
wav_spec.samples = SAMPLE_COUNT * 2; // Must be power of two
|
wav_spec.samples = SAMPLE_COUNT * 2; // Must be power of two
|
||||||
wav_spec.callback = audioCallback;
|
wav_spec.callback = audioCallback;
|
||||||
wav_spec.userdata = this;
|
wav_spec.userdata = this;
|
||||||
|
needs_resampling = false;
|
||||||
|
|
||||||
// Try 44.1KHz which should be faster since it's native.
|
// Try 44.1KHz which should be faster since it's native.
|
||||||
audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0);
|
audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0);
|
||||||
|
@ -126,7 +130,7 @@ public:
|
||||||
// If wait, then wait for the buffer to be smaller than a certain size.
|
// If wait, then wait for the buffer to be smaller than a certain size.
|
||||||
stream_mutex.lock();
|
stream_mutex.lock();
|
||||||
if (wait) {
|
if (wait) {
|
||||||
while (sample_count + samples > (u32)config::AudioBufferSize) {
|
while (sample_count + samples > sample_buffer_size) {
|
||||||
stream_mutex.unlock();
|
stream_mutex.unlock();
|
||||||
read_wait.Wait();
|
read_wait.Wait();
|
||||||
stream_mutex.lock();
|
stream_mutex.lock();
|
||||||
|
@ -134,7 +138,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy as many samples as possible, drop any remaining (this should not happen usually)
|
// Copy as many samples as possible, drop any remaining (this should not happen usually)
|
||||||
unsigned free_samples = config::AudioBufferSize - sample_count;
|
unsigned free_samples = sample_buffer_size - sample_count;
|
||||||
unsigned tocopy = samples < free_samples ? samples : free_samples;
|
unsigned tocopy = samples < free_samples ? samples : free_samples;
|
||||||
memcpy(&sample_buffer[sample_count], frame, tocopy * sizeof(uint32_t));
|
memcpy(&sample_buffer[sample_count], frame, tocopy * sizeof(uint32_t));
|
||||||
sample_count += tocopy;
|
sample_count += tocopy;
|
||||||
|
|
Loading…
Reference in New Issue