alsa: cleanups

Use a periodic timer to catch underruns
Small cleanups
This commit is contained in:
Wim Taymans 2018-05-11 09:56:46 +02:00
parent 97473c8e8b
commit bd3b7e8ee4
8 changed files with 27 additions and 24 deletions

View file

@ -491,10 +491,10 @@ impl_node_port_use_buffers(struct spa_node *node,
struct spa_data *d = buffers[i]->datas; struct spa_data *d = buffers[i]->datas;
uint32_t type; uint32_t type;
b->outbuf = buffers[i]; b->buf = buffers[i];
b->flags = BUFFER_FLAG_OUT; b->flags = BUFFER_FLAG_OUT;
b->h = spa_buffer_find_meta(b->outbuf, this->type.meta.Header); b->h = spa_buffer_find_meta(b->buf, this->type.meta.Header);
type = d[0].type; type = d[0].type;
if ((type == this->type.data.MemFd || if ((type == this->type.data.MemFd ||
@ -597,11 +597,12 @@ static int impl_node_process(struct spa_node *node)
input->status = -EINVAL; input->status = -EINVAL;
return -EINVAL; return -EINVAL;
} }
spa_log_trace(this->log, NAME " %p: queue buffer %u", this, input->buffer_id); spa_log_trace(this->log, NAME " %p: queue buffer %u", this, input->buffer_id);
spa_list_append(&this->ready, &b->link); spa_list_append(&this->ready, &b->link);
SPA_FLAG_UNSET(b->flags, BUFFER_FLAG_OUT); SPA_FLAG_UNSET(b->flags, BUFFER_FLAG_OUT);
this->threshold = b->buf->datas[0].chunk->size / this->frame_size;
spa_alsa_write(this, 0); spa_alsa_write(this, 0);
input->status = SPA_STATUS_OK; input->status = SPA_STATUS_OK;

View file

@ -512,10 +512,10 @@ impl_node_port_use_buffers(struct spa_node *node,
struct buffer *b = &this->buffers[i]; struct buffer *b = &this->buffers[i];
struct spa_data *d = buffers[i]->datas; struct spa_data *d = buffers[i]->datas;
b->outbuf = buffers[i]; b->buf = buffers[i];
b->flags = 0; b->flags = 0;
b->h = spa_buffer_find_meta(b->outbuf, this->type.meta.Header); b->h = spa_buffer_find_meta(b->buf, this->type.meta.Header);
if (!((d[0].type == this->type.data.MemFd || if (!((d[0].type == this->type.data.MemFd ||
d[0].type == this->type.data.DmaBuf || d[0].type == this->type.data.DmaBuf ||
@ -637,9 +637,9 @@ static int impl_node_process(struct spa_node *node)
b = spa_list_first(&this->ready, struct buffer, link); b = spa_list_first(&this->ready, struct buffer, link);
spa_list_remove(&b->link); spa_list_remove(&b->link);
spa_log_trace(this->log, NAME " %p: dequeue buffer %d", node, b->outbuf->id); spa_log_trace(this->log, NAME " %p: dequeue buffer %d", node, b->buf->id);
io->buffer_id = b->outbuf->id; io->buffer_id = b->buf->id;
io->status = SPA_STATUS_HAVE_BUFFER; io->status = SPA_STATUS_HAVE_BUFFER;
return SPA_STATUS_HAVE_BUFFER; return SPA_STATUS_HAVE_BUFFER;

View file

@ -365,7 +365,7 @@ static int set_timeout(struct state *state, size_t extra)
calc_timeout(state->filled + extra, state->threshold, state->rate, &state->now, &ts.it_value); calc_timeout(state->filled + extra, state->threshold, state->rate, &state->now, &ts.it_value);
ts.it_interval.tv_sec = 0; ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0; ts.it_interval.tv_nsec = ((size_t)state->threshold * SPA_NSEC_PER_SEC) / state->rate;
timerfd_settime(state->timerfd, TFD_TIMER_ABSTIME, &ts, NULL); timerfd_settime(state->timerfd, TFD_TIMER_ABSTIME, &ts, NULL);
return 0; return 0;
@ -396,7 +396,7 @@ int spa_alsa_write(struct state *state, snd_pcm_uframes_t silence)
uint32_t index, offs, avail, size, maxsize, l0, l1; uint32_t index, offs, avail, size, maxsize, l0, l1;
b = spa_list_first(&state->ready, struct buffer, link); b = spa_list_first(&state->ready, struct buffer, link);
d = b->outbuf->datas; d = b->buf->datas;
dst = SPA_MEMBER(my_areas[0].addr, offset * state->frame_size, uint8_t); dst = SPA_MEMBER(my_areas[0].addr, offset * state->frame_size, uint8_t);
src = d[0].data; src = d[0].data;
@ -424,8 +424,8 @@ int spa_alsa_write(struct state *state, snd_pcm_uframes_t silence)
if (state->ready_offset >= size) { if (state->ready_offset >= size) {
spa_list_remove(&b->link); spa_list_remove(&b->link);
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT); SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
spa_log_trace(state->log, "alsa-util %p: reuse buffer %u", state, b->outbuf->id); spa_log_trace(state->log, "alsa-util %p: reuse buffer %u", state, b->buf->id);
state->callbacks->reuse_buffer(state->callbacks_data, 0, b->outbuf->id); state->callbacks->reuse_buffer(state->callbacks_data, 0, b->buf->id);
state->ready_offset = 0; state->ready_offset = 0;
} }
written += n_frames; written += n_frames;
@ -489,7 +489,7 @@ push_frames(struct state *state,
b->h->dts_offset = 0; b->h->dts_offset = 0;
} }
d = b->outbuf->datas; d = b->buf->datas;
src = SPA_MEMBER(my_areas[0].addr, offset * state->frame_size, uint8_t); src = SPA_MEMBER(my_areas[0].addr, offset * state->frame_size, uint8_t);
@ -577,11 +577,12 @@ static void alsa_on_playback_timeout_event(struct spa_source *source)
if (spa_list_is_empty(&state->ready)) { if (spa_list_is_empty(&state->ready)) {
struct spa_io_buffers *io = state->io; struct spa_io_buffers *io = state->io;
if (state->filled == 0) if (state->filled == 0) {
if (state->alsa_started)
spa_log_warn(state->log,
"alsa-util %p: underrun", state);
spa_alsa_write(state, state->threshold); spa_alsa_write(state, state->threshold);
else }
set_timeout(state, state->threshold);
spa_log_trace(state->log, "alsa-util %p: %d %lu", state, io->status, spa_log_trace(state->log, "alsa-util %p: %d %lu", state, io->status,
state->filled); state->filled);

View file

@ -51,7 +51,7 @@ struct props {
#define MAX_BUFFERS 32 #define MAX_BUFFERS 32
struct buffer { struct buffer {
struct spa_buffer *outbuf; struct spa_buffer *buf;
struct spa_meta_header *h; struct spa_meta_header *h;
#define BUFFER_FLAG_OUT (1<<0) #define BUFFER_FLAG_OUT (1<<0)
uint32_t flags; uint32_t flags;

View file

@ -521,7 +521,7 @@ impl_node_port_enum_params(struct spa_node *node,
static int clear_buffers(struct impl *this, struct port *port) static int clear_buffers(struct impl *this, struct port *port)
{ {
if (port->n_buffers > 0) { if (port->n_buffers > 0) {
spa_log_info(this->log, NAME " %p: clear buffers %p", this, port); spa_log_debug(this->log, NAME " %p: clear buffers %p", this, port);
port->n_buffers = 0; port->n_buffers = 0;
spa_list_init(&port->queue); spa_list_init(&port->queue);
} }
@ -577,7 +577,7 @@ static int port_set_format(struct spa_node *node,
port->format = info; port->format = info;
port->have_format = true; port->have_format = true;
spa_log_info(this->log, NAME " %p: set format on port %d %d", this, port_id, res); spa_log_debug(this->log, NAME " %p: set format on port %d %d", this, port_id, res);
} }
return res; return res;
} }
@ -628,7 +628,7 @@ impl_node_port_use_buffers(struct spa_node *node,
spa_return_val_if_fail(port->have_format, -EIO); spa_return_val_if_fail(port->have_format, -EIO);
spa_log_info(this->log, NAME " %p: use buffers %d on port %d", this, n_buffers, port_id); spa_log_debug(this->log, NAME " %p: use buffers %d on port %d", this, n_buffers, port_id);
clear_buffers(this, port); clear_buffers(this, port);

View file

@ -163,7 +163,7 @@ static int setup_convert(struct impl *this)
src_fmt = inport->format.info.raw.format; src_fmt = inport->format.info.raw.format;
dst_fmt = outport->format.info.raw.format; dst_fmt = outport->format.info.raw.format;
spa_log_debug(this->log, NAME " %p: %s/%d@%d.%d->%s/%d@%d.%d", this, spa_log_info(this->log, NAME " %p: %s/%d@%d.%d->%s/%d@%d.%d", this,
spa_type_map_get_type(this->map, src_fmt), spa_type_map_get_type(this->map, src_fmt),
inport->format.info.raw.channels, inport->format.info.raw.channels,
inport->format.info.raw.rate, inport->format.info.raw.rate,

View file

@ -497,7 +497,7 @@ impl_node_port_enum_params(struct spa_node *node,
static int clear_buffers(struct impl *this, struct port *port) static int clear_buffers(struct impl *this, struct port *port)
{ {
if (port->n_buffers > 0) { if (port->n_buffers > 0) {
spa_log_info(this->log, NAME " %p: clear buffers %p", this, port); spa_log_debug(this->log, NAME " %p: clear buffers %p", this, port);
port->n_buffers = 0; port->n_buffers = 0;
spa_list_init(&port->queue); spa_list_init(&port->queue);
} }
@ -552,7 +552,7 @@ static int port_set_format(struct spa_node *node,
port->format = info; port->format = info;
port->have_format = true; port->have_format = true;
spa_log_info(this->log, NAME " %p: set format on port %d %d", this, port_id, res); spa_log_debug(this->log, NAME " %p: set format on port %d %d", this, port_id, res);
} }
return res; return res;
} }
@ -603,7 +603,7 @@ impl_node_port_use_buffers(struct spa_node *node,
spa_return_val_if_fail(port->have_format, -EIO); spa_return_val_if_fail(port->have_format, -EIO);
spa_log_info(this->log, NAME " %p: use buffers %d on port %d", this, n_buffers, port_id); spa_log_debug(this->log, NAME " %p: use buffers %d on port %d", this, n_buffers, port_id);
clear_buffers(this, port); clear_buffers(this, port);

View file

@ -1011,6 +1011,7 @@ impl_node_port_enum_params(struct spa_node *node,
"I", t->media_type.audio, "I", t->media_type.audio,
"I", t->media_subtype.raw, "I", t->media_subtype.raw,
":", t->format_audio.format, "I", t->audio_format.S16, ":", t->format_audio.format, "I", t->audio_format.S16,
":", t->format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
":", t->format_audio.rate, "i", rate, ":", t->format_audio.rate, "i", rate,
":", t->format_audio.channels, "i", channels); ":", t->format_audio.channels, "i", channels);
} }