v4l2: fix buffer recycle

Only set the OUTSTANDING flag when we placed the buffer in an
io area and need to recycle it later.
When we captured a frame, put it in the queue. Then dequeue it
into the io area after recycling buffers.

Fixes #217
This commit is contained in:
Wim Taymans 2020-03-19 13:15:49 +01:00
parent 441fdb2333
commit a9b191971c
2 changed files with 23 additions and 15 deletions

View file

@ -859,6 +859,7 @@ static int impl_node_process(void *object)
b = spa_list_first(&port->queue, struct buffer, link);
spa_list_remove(&b->link);
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
spa_log_trace(this->log, NAME " %p: dequeue buffer %d", this, b->id);

View file

@ -1165,7 +1165,6 @@ static int mmap_read(struct impl *this)
{
struct port *port = &this->out_ports[0];
struct spa_v4l2_device *dev = &port->dev;
struct spa_io_buffers *io;
struct v4l2_buffer buf;
struct buffer *b;
struct spa_data *d;
@ -1210,26 +1209,16 @@ static int mmap_read(struct impl *this)
if (buf.flags & V4L2_BUF_FLAG_ERROR)
d[0].flags |= SPA_CHUNK_FLAG_CORRUPTED;
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
io = port->io;
if (io != NULL && io->status != SPA_STATUS_HAVE_DATA) {
io->buffer_id = b->id;
io->status = SPA_STATUS_HAVE_DATA;
}
else {
spa_list_append(&port->queue, &b->link);
}
spa_log_trace(this->log, "v4l2 %p: now queued %d", this, b->id);
spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
spa_list_append(&port->queue, &b->link);
return 0;
}
static void v4l2_on_fd_events(struct spa_source *source)
{
struct impl *this = source->data;
struct spa_io_buffers *io;
struct port *port = &this->out_ports[0];
struct buffer *b;
if (source->rmask & SPA_IO_ERR) {
struct port *port = &this->out_ports[0];
@ -1246,6 +1235,24 @@ static void v4l2_on_fd_events(struct spa_source *source)
if (mmap_read(this) < 0)
return;
if (spa_list_is_empty(&port->queue))
return;
io = port->io;
if (io != NULL && io->status != SPA_STATUS_HAVE_DATA) {
if (io->buffer_id < port->n_buffers)
spa_v4l2_buffer_recycle(this, io->buffer_id);
b = spa_list_first(&port->queue, struct buffer, link);
spa_list_remove(&b->link);
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
io->buffer_id = b->id;
io->status = SPA_STATUS_HAVE_DATA;
spa_log_trace(this->log, "v4l2 %p: now queued %d", this, b->id);
}
spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
}
static int spa_v4l2_use_buffers(struct impl *this, struct spa_buffer **buffers, uint32_t n_buffers)