improve node io

Unify input and output io areas.
Add support for ranges in the io area.
Automatically recycle buffers in the output areas in process_output
Improve the mixer, add use_buffer support, use a queue of input buffers,
fix mixing, add support for ranges.
Fix mixer and v4l2 tests
This commit is contained in:
Wim Taymans 2017-04-03 14:56:04 +02:00
parent 29fbf2e841
commit 01c13adab5
28 changed files with 983 additions and 747 deletions

View file

@ -528,12 +528,16 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
info.media_type = SPA_FORMAT_MEDIA_TYPE (format);
info.media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
if (info.media_type != this->type.media_type.video)
if (info.media_type != this->type.media_type.video) {
spa_log_error (this->log, "media type must be video");
return SPA_RESULT_INVALID_MEDIA_TYPE;
}
if (info.media_subtype == this->type.media_subtype.raw) {
if (!spa_format_video_raw_parse (format, &info.info.raw, &this->type.format_video))
if (!spa_format_video_raw_parse (format, &info.info.raw, &this->type.format_video)) {
spa_log_error (this->log, "can't parse video raw");
return SPA_RESULT_INVALID_MEDIA_TYPE;
}
if (state->have_format && info.media_type == state->current_format.media_type &&
info.media_subtype == state->current_format.media_subtype &&
@ -761,17 +765,10 @@ spa_v4l2_source_node_port_alloc_buffers (SpaNode *node,
}
static SpaResult
spa_v4l2_source_node_port_set_input (SpaNode *node,
uint32_t port_id,
SpaPortInput *input)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_v4l2_source_node_port_set_output (SpaNode *node,
uint32_t port_id,
SpaPortOutput *output)
spa_v4l2_source_node_port_set_io (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortIO *io)
{
SpaV4l2Source *this;
@ -780,15 +777,14 @@ spa_v4l2_source_node_port_set_output (SpaNode *node,
this = SPA_CONTAINER_OF (node, SpaV4l2Source, node);
if (!CHECK_PORT (this, SPA_DIRECTION_OUTPUT, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
this->state[port_id].io = output;
this->state[port_id].io = io;
return SPA_RESULT_OK;
}
static SpaResult
spa_v4l2_source_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
@ -834,7 +830,8 @@ spa_v4l2_source_node_port_send_command (SpaNode *node,
}
else if (SPA_COMMAND_TYPE (command) == this->type.command_node.Start) {
res = spa_v4l2_port_set_enabled (this, true);
} else
}
else
res = SPA_RESULT_NOT_IMPLEMENTED;
return res;
@ -849,7 +846,22 @@ spa_v4l2_source_node_process_input (SpaNode *node)
static SpaResult
spa_v4l2_source_node_process_output (SpaNode *node)
{
return SPA_RESULT_OK;
SpaV4l2Source *this;
SpaResult res = SPA_RESULT_OK;
SpaPortIO *io;
if (node == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = SPA_CONTAINER_OF (node, SpaV4l2Source, node);
if ((io = this->state[0].io)) {
if (io->buffer_id != SPA_ID_INVALID) {
res = spa_v4l2_buffer_recycle (this, io->buffer_id);
io->buffer_id = SPA_ID_INVALID;
}
}
return res;
}
static const SpaNode v4l2source_node = {
@ -872,8 +884,7 @@ static const SpaNode v4l2source_node = {
spa_v4l2_source_node_port_set_props,
spa_v4l2_source_node_port_use_buffers,
spa_v4l2_source_node_port_alloc_buffers,
spa_v4l2_source_node_port_set_input,
spa_v4l2_source_node_port_set_output,
spa_v4l2_source_node_port_set_io,
spa_v4l2_source_node_port_reuse_buffer,
spa_v4l2_source_node_port_send_command,
spa_v4l2_source_node_process_input,

View file

@ -90,6 +90,7 @@ spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
return SPA_RESULT_OK;
b->outstanding = false;
spa_log_trace (state->log, "v4l2 %p: recycle buffer %d", this, buffer_id);
if (xioctl (state->fd, VIDIOC_QBUF, &b->v4l2_buffer) < 0) {
perror ("VIDIOC_QBUF");
@ -916,7 +917,7 @@ mmap_read (SpaV4l2Source *this)
V4l2Buffer *b;
SpaData *d;
int64_t pts;
SpaPortOutput *output;
SpaPortIO *io;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@ -955,10 +956,14 @@ mmap_read (SpaV4l2Source *this)
d[0].chunk->size = buf.bytesused;
d[0].chunk->stride = state->fmt.fmt.pix.bytesperline;
if ((output = state->io)) {
if ((io = state->io)) {
SpaEvent event = SPA_EVENT_INIT (this->type.event_node.HaveOutput);
b->outstanding = true;
output->buffer_id = b->outbuf->id;
output->status = SPA_RESULT_OK;
io->buffer_id = b->outbuf->id;
io->status = SPA_RESULT_OK;
this->event_cb (&this->node, &event, this->user_data);
}
return SPA_RESULT_OK;
}
@ -976,11 +981,6 @@ v4l2_on_fd_events (SpaSource *source)
if (mmap_read (this) < 0)
return;
{
SpaEvent event = SPA_EVENT_INIT (this->type.event_node.HaveOutput);
this->event_cb (&this->node, &event, this->user_data);
}
}
static SpaResult