alsa: some cleanups

Make sure we recycle an old buffer even if we don't have a new buffer to
push.
This commit is contained in:
Wim Taymans 2023-09-15 13:05:31 +02:00
parent bf5b526464
commit c8db951d61

View file

@ -2252,10 +2252,10 @@ static int alsa_write_sync(struct state *state, uint64_t current_time)
snd_pcm_uframes_t avail, delay, target; snd_pcm_uframes_t avail, delay, target;
bool following = state->following; bool following = state->following;
if (!state->alsa_started) if (SPA_UNLIKELY(!state->alsa_started))
return 0; return 0;
if ((res = check_position_config(state)) < 0) if (SPA_UNLIKELY((res = check_position_config(state)) < 0))
return res; return res;
if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0)) if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0))
@ -2420,9 +2420,7 @@ int spa_alsa_write(struct state *state)
if ((res = alsa_write_sync(state, current_time)) < 0) if ((res = alsa_write_sync(state, current_time)) < 0)
return res; return res;
} }
if ((res = alsa_write_frames(state)) < 0) return alsa_write_frames(state);
return res;
return 0;
} }
void spa_alsa_recycle_buffer(struct state *this, uint32_t buffer_id) void spa_alsa_recycle_buffer(struct state *this, uint32_t buffer_id)
@ -2514,13 +2512,13 @@ static int alsa_read_sync(struct state *state, uint64_t current_time)
snd_pcm_uframes_t avail, delay, target, max_read; snd_pcm_uframes_t avail, delay, target, max_read;
bool following = state->following; bool following = state->following;
if (!state->alsa_started) if (SPA_UNLIKELY(!state->alsa_started))
return 0; return 0;
if ((res = check_position_config(state)) < 0) if (SPA_UNLIKELY((res = check_position_config(state)) < 0))
return res; return res;
if ((res = get_status(state, current_time, &avail, &delay, &target)) < 0) if (SPA_UNLIKELY((res = get_status(state, current_time, &avail, &delay, &target)) < 0))
return res; return res;
if (SPA_UNLIKELY(!following && avail < state->read_size)) { if (SPA_UNLIKELY(!following && avail < state->read_size)) {
@ -2630,9 +2628,7 @@ int spa_alsa_read(struct state *state)
if ((res = alsa_read_sync(state, current_time)) < 0) if ((res = alsa_read_sync(state, current_time)) < 0)
return res; return res;
} }
if ((res = alsa_read_frames(state)) < 0) return alsa_read_frames(state);
return res;
return 0;
} }
int spa_alsa_skip(struct state *state) int spa_alsa_skip(struct state *state)
@ -2641,7 +2637,7 @@ int spa_alsa_skip(struct state *state)
struct spa_data *d; struct spa_data *d;
uint32_t i, avail, total_frames, n_bytes, frames; uint32_t i, avail, total_frames, n_bytes, frames;
if (spa_list_is_empty(&state->free)) { if (SPA_UNLIKELY(spa_list_is_empty(&state->free))) {
spa_log_warn(state->log, "%s: no more buffers", state->name); spa_log_warn(state->log, "%s: no more buffers", state->name);
return -EPIPE; return -EPIPE;
} }
@ -2684,27 +2680,32 @@ static int playback_ready(struct state *state)
static int capture_ready(struct state *state) static int capture_ready(struct state *state)
{ {
struct spa_io_buffers *io; struct spa_io_buffers *io;
bool have_data;
if (spa_list_is_empty(&state->ready)) have_data = !spa_list_is_empty(&state->ready);
return 0;
io = state->io; io = state->io;
if (io != NULL && if (io != NULL &&
(io->status != SPA_STATUS_HAVE_DATA || state->rate_match != NULL)) { (io->status != SPA_STATUS_HAVE_DATA || state->rate_match != NULL)) {
struct buffer *b; struct buffer *b;
if (io->buffer_id < state->n_buffers) if (SPA_LIKELY(io->buffer_id < state->n_buffers))
spa_alsa_recycle_buffer(state, io->buffer_id); spa_alsa_recycle_buffer(state, io->buffer_id);
b = spa_list_first(&state->ready, struct buffer, link); if (SPA_LIKELY(have_data)) {
spa_list_remove(&b->link); b = spa_list_first(&state->ready, struct buffer, link);
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT); spa_list_remove(&b->link);
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
io->buffer_id = b->id; io->buffer_id = b->id;
io->status = SPA_STATUS_HAVE_DATA; io->status = SPA_STATUS_HAVE_DATA;
} else {
io->buffer_id = SPA_ID_INVALID;
}
spa_log_trace_fp(state->log, "%p: output buffer:%d", state, b->id); spa_log_trace_fp(state->log, "%p: output buffer:%d", state, b->id);
} }
spa_node_call_ready(&state->callbacks, SPA_STATUS_HAVE_DATA); if (have_data)
spa_node_call_ready(&state->callbacks, SPA_STATUS_HAVE_DATA);
return 0; return 0;
} }
@ -2768,7 +2769,7 @@ static void alsa_wakeup_event(struct spa_source *source)
else else
res = alsa_write_sync(state, current_time); res = alsa_write_sync(state, current_time);
/* we can get -EAGAIN when we need to wait some more */ /* we can get -EAGAIN when we need to wait some more */
if (res == -EAGAIN) if (SPA_UNLIKELY(res == -EAGAIN))
goto done; goto done;
/* then read all sources, the sinks will be written to when the /* then read all sources, the sinks will be written to when the