handle set_format with existing format

If one calls set-format with the current format, we return success
Remove some unused utils now
Work on cleanup of buffers
This commit is contained in:
Wim Taymans 2016-08-11 11:20:12 +02:00
parent 55c3262a6a
commit ab0537305f
9 changed files with 82 additions and 143 deletions

View file

@ -91,7 +91,7 @@ typedef struct {
void *cookie;
V4l2Format format[2];
SpaFormat *current_format;
V4l2Format *current_format;
int fd;
bool opened;
@ -412,12 +412,21 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
f = (V4l2Format*)format;
}
if (state->current_format) {
if (f->fmt.media_type == state->current_format->fmt.media_type &&
f->fmt.media_subtype == state->current_format->fmt.media_subtype &&
f->format == state->current_format->format &&
f->size.width == state->current_format->size.width &&
f->size.height == state->current_format->size.height)
return SPA_RESULT_OK;
}
if (spa_v4l2_set_format (this, f, flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY) < 0)
return SPA_RESULT_INVALID_MEDIA_TYPE;
if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
memcpy (tf, f, fs);
state->current_format = &tf->fmt;
state->current_format = tf;
}
return SPA_RESULT_OK;
@ -444,7 +453,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
if (state->current_format == NULL)
return SPA_RESULT_NO_FORMAT;
*format = state->current_format;
*format = &state->current_format->fmt;
return SPA_RESULT_OK;
}

View file

@ -325,7 +325,11 @@ again:
i = ++state->frmival.index;
}
fmt->infos[pi].n_range_values = i;
fmt->fmt.props.unset_mask |= 1 << pi;
if (i == 1) {
fmt->framerate = fmt->framerates[0];
} else {
fmt->fmt.props.unset_mask |= 1 << pi;
}
pi = ++fmt->fmt.props.n_prop_info;
*format = &state->format[0].fmt;
@ -488,6 +492,9 @@ spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
SpaV4l2State *state = &this->state[0];
V4l2Buffer *b = &state->alloc_buffers[buffer_id];
if (!b->outstanding)
return;
b->outstanding = false;
if (xioctl (state->fd, VIDIOC_QBUF, &b->v4l2_buffer) < 0) {
@ -495,6 +502,38 @@ spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
}
}
static void
clear_buffers (SpaV4l2Source *this)
{
SpaV4l2State *state = &this->state[0];
int i;
if (!state->have_buffers)
return;
for (i = 0; i < state->reqbuf.count; i++) {
V4l2Buffer *b;
SpaMemory *mem;
b = &state->alloc_buffers[i];
if (b->outstanding) {
fprintf (stderr, "queueing outstanding buffer %p\n", b);
spa_v4l2_buffer_recycle (this, i);
}
mem = spa_memory_find (&b->datas[0].mem.mem);
if (state->export_buf) {
close (mem->fd);
} else {
munmap (mem->ptr, mem->size);
}
spa_memory_unref (&mem->mem);
}
if (state->alloc_mem)
spa_memory_unref (&state->alloc_mem->mem);
state->have_buffers = false;
}
static SpaResult
spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_buffers)
{
@ -502,6 +541,11 @@ spa_v4l2_import_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_bu
struct v4l2_requestbuffers reqbuf;
int i;
if (buffers == NULL) {
clear_buffers (this);
return SPA_RESULT_OK;
}
state->memtype = V4L2_MEMORY_USERPTR;
CLEAR(reqbuf);
@ -715,6 +759,18 @@ spa_v4l2_alloc_buffers (SpaV4l2Source *this,
{
SpaResult res;
SpaV4l2State *state = &this->state[0];
unsigned int i;
if (state->have_buffers) {
if (*n_buffers < state->reqbuf.count)
return SPA_RESULT_NO_BUFFERS;
*n_buffers = state->reqbuf.count;
for (i = 0; i < state->reqbuf.count; i++) {
buffers[i] = &state->alloc_buffers[i].buffer;
}
return SPA_RESULT_OK;
}
if (state->cap.capabilities & V4L2_CAP_STREAMING) {
if ((res = mmap_init (this, params, n_params, buffers, n_buffers)) < 0)
@ -774,7 +830,6 @@ spa_v4l2_stop (SpaV4l2Source *this)
SpaV4l2State *state = &this->state[0];
enum v4l2_buf_type type;
SpaEvent event;
int i;
if (!state->opened)
return SPA_RESULT_OK;
@ -785,24 +840,7 @@ spa_v4l2_stop (SpaV4l2Source *this)
return SPA_RESULT_ERROR;
}
for (i = 0; i < state->reqbuf.count; i++) {
V4l2Buffer *b;
SpaMemory *mem;
b = &state->alloc_buffers[i];
if (b->outstanding) {
fprintf (stderr, "queueing outstanding buffer %p\n", b);
spa_v4l2_buffer_recycle (this, i);
}
mem = spa_memory_find (&b->datas[0].mem.mem);
if (state->export_buf) {
close (mem->fd);
} else {
munmap (mem->ptr, mem->size);
}
spa_memory_unref (&mem->mem);
}
state->have_buffers = false;
clear_buffers (this);
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
event.port_id = 0;