diff options
author | Matthew Gregan <[email protected]> | 2022-03-26 13:50:32 +1300 |
---|---|---|
committer | Matthew Gregan <[email protected]> | 2022-03-30 18:12:01 +1300 |
commit | b62d61bc661b49c7a7f5d97f4657189c630ac7a5 (patch) | |
tree | c1d774314a0d474ee8f489ce18f378a4fe1a14ab | |
parent | 16c2a521525ae91c376eaa8a49b99ecccd89e066 (diff) | |
download | cubeb-b62d61bc661b49c7a7f5d97f4657189c630ac7a5.tar.gz cubeb-b62d61bc661b49c7a7f5d97f4657189c630ac7a5.zip |
audiounit,pulse,wasapi: Handle data_callback errors and signal to user via state_callback.
-rw-r--r-- | src/cubeb_audiounit.cpp | 7 | ||||
-rw-r--r-- | src/cubeb_pulse.c | 4 | ||||
-rw-r--r-- | src/cubeb_wasapi.cpp | 29 |
3 files changed, 31 insertions, 9 deletions
diff --git a/src/cubeb_audiounit.cpp b/src/cubeb_audiounit.cpp index 8f2741a..37036a3 100644 --- a/src/cubeb_audiounit.cpp +++ b/src/cubeb_audiounit.cpp @@ -541,6 +541,13 @@ audiounit_input_callback(void * user_ptr, AudioUnitRenderActionFlags * flags, long outframes = cubeb_resampler_fill(stm->resampler.get(), stm->input_linear_buffer->data(), &total_input_frames, NULL, 0); + if (outframes < 0) { + stm->shutdown = true; + OSStatus r = AudioOutputUnitStop(stm->input_unit); + assert(r == 0); + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); + return noErr; + } stm->draining = outframes < total_input_frames; // Reset input buffer diff --git a/src/cubeb_pulse.c b/src/cubeb_pulse.c index 3ed6bdc..13f6791 100644 --- a/src/cubeb_pulse.c +++ b/src/cubeb_pulse.c @@ -280,6 +280,7 @@ trigger_user_callback(pa_stream * s, void const * input_data, size_t nbytes, if (got < 0) { WRAP(pa_stream_cancel_write)(s); stm->shutdown = 1; + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); return; } // If more iterations move offset of read buffer @@ -392,6 +393,9 @@ stream_read_callback(pa_stream * s, size_t nbytes, void * u) if (got < 0 || (size_t)got != read_frames) { WRAP(pa_stream_cancel_write)(s); stm->shutdown = 1; + if (got < 0) { + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); + } break; } } diff --git a/src/cubeb_wasapi.cpp b/src/cubeb_wasapi.cpp index 90e1950..9d5e18f 100644 --- a/src/cubeb_wasapi.cpp +++ b/src/cubeb_wasapi.cpp @@ -873,8 +873,11 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count, long out_frames = cubeb_resampler_fill(stm->resampler.get(), input_buffer, &input_frames_count, dest, output_frames_needed); - /* TODO: Report out_frames < 0 as an error via the API. */ - XASSERT(out_frames >= 0); + if (out_frames < 0) { + ALOGV("Callback refill error: %d", out_frames); + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR); + return out_frames; + } float volume = 1.0; { @@ -1190,6 +1193,7 @@ refill_callback_duplex(cubeb_stream * stm) static_cast<long>(stm->total_output_frames) - stm->total_input_frames, static_cast<float>(stm->total_output_frames) / stm->total_input_frames); + long got; if (stm->has_dummy_output) { ALOGV( "Duplex callback (dummy output): input frames: %Iu, output frames: %Iu", @@ -1197,13 +1201,15 @@ refill_callback_duplex(cubeb_stream * stm) // We don't want to expose the dummy output to the callback so don't pass // the output buffer (it will be released later with silence in it) - refill(stm, stm->linear_input_buffer->data(), input_frames, nullptr, 0); + got = + refill(stm, stm->linear_input_buffer->data(), input_frames, nullptr, 0); + } else { ALOGV("Duplex callback: input frames: %Iu, output frames: %Iu", input_frames, output_frames); - refill(stm, stm->linear_input_buffer->data(), input_frames, output_buffer, - output_frames); + got = refill(stm, stm->linear_input_buffer->data(), input_frames, + output_buffer, output_frames); } stm->linear_input_buffer->clear(); @@ -1219,6 +1225,9 @@ refill_callback_duplex(cubeb_stream * stm) LOG("failed to release buffer: %lx", hr); return false; } + if (got < 0) { + return false; + } return true; } @@ -1245,8 +1254,9 @@ refill_callback_input(cubeb_stream * stm) long read = refill(stm, stm->linear_input_buffer->data(), input_frames, nullptr, 0); - - XASSERT(read >= 0); + if (read < 0) { + return false; + } stm->linear_input_buffer->clear(); @@ -1276,8 +1286,9 @@ refill_callback_output(cubeb_stream * stm) ALOGV("Output callback: output frames requested: %Iu, got %ld", output_frames, got); - - XASSERT(got >= 0); + if (got < 0) { + return false; + } XASSERT(size_t(got) == output_frames || stm->draining); hr = stm->render_client->ReleaseBuffer(got, 0); |