Remove some events

Remove port added and port removed, we can get that info by inspecting
the port ids.
Remove data from ringbuffer, we just need the ringbuffer to keep track
of the read and write positions.
Handle async-complete in the main thread
Work on async node initialization
Work on using a queue as the link between nodes
Make the daemon link things based on the node states
Use queue helper in v4l2
This commit is contained in:
Wim Taymans 2016-09-23 17:08:20 +02:00
parent 68148188fa
commit 1ba10cf848
17 changed files with 366 additions and 273 deletions

View file

@ -59,10 +59,9 @@ typedef enum {
/* client to server */
SPA_CONTROL_CMD_NODE_UPDATE = 1,
SPA_CONTROL_CMD_PORT_UPDATE = 2,
SPA_CONTROL_CMD_PORT_REMOVED = 3,
SPA_CONTROL_CMD_NODE_STATE_CHANGE = 4,
SPA_CONTROL_CMD_NODE_STATE_CHANGE = 3,
SPA_CONTROL_CMD_PORT_STATUS_CHANGE = 5,
SPA_CONTROL_CMD_PORT_STATUS_CHANGE = 4,
/* server to client */
SPA_CONTROL_CMD_ADD_PORT = 32,
@ -109,11 +108,6 @@ typedef struct {
const SpaPortInfo *info;
} SpaControlCmdPortUpdate;
/* SPA_CONTROL_CMD_PORT_REMOVED */
typedef struct {
uint32_t port_id;
} SpaControlCmdPortRemoved;
/* SPA_CONTROL_CMD_PORT_STATUS_CHANGE */
/* SPA_CONTROL_CMD_NODE_STATE_CHANGE */

View file

@ -34,8 +34,6 @@ typedef struct _SpaNodeEvent SpaNodeEvent;
* SpaEventType:
* @SPA_NODE_EVENT_TYPE_INVALID: invalid event, should be ignored
* @SPA_NODE_EVENT_TYPE_ASYNC_COMPLETE: an async operation completed
* @SPA_NODE_EVENT_TYPE_PORT_ADDED: a new port is added
* @SPA_NODE_EVENT_TYPE_PORT_REMOVED: a port is removed
* @SPA_NODE_EVENT_TYPE_HAVE_OUTPUT: emited when an async node has output that can be pulled
* @SPA_NODE_EVENT_TYPE_NEED_INPUT: emited when more data can be pushed to an async node
* @SPA_NODE_EVENT_TYPE_REUSE_BUFFER: emited when a buffer can be reused
@ -47,12 +45,11 @@ typedef struct _SpaNodeEvent SpaNodeEvent;
* @SPA_NODE_EVENT_TYPE_ERROR: emited when error occured
* @SPA_NODE_EVENT_TYPE_BUFFERING: emited when buffering is in progress
* @SPA_NODE_EVENT_TYPE_REQUEST_REFRESH: emited when a keyframe refresh is needed
* @SPA_NODE_EVENT_TYPE_REQUEST_CLOCK_UPDATE: the element asks for a clock update
*/
typedef enum {
SPA_NODE_EVENT_TYPE_INVALID = 0,
SPA_NODE_EVENT_TYPE_ASYNC_COMPLETE,
SPA_NODE_EVENT_TYPE_PORT_ADDED,
SPA_NODE_EVENT_TYPE_PORT_REMOVED,
SPA_NODE_EVENT_TYPE_HAVE_OUTPUT,
SPA_NODE_EVENT_TYPE_NEED_INPUT,
SPA_NODE_EVENT_TYPE_REUSE_BUFFER,

View file

@ -29,20 +29,18 @@ typedef struct _SpaRingbuffer SpaRingbuffer;
#include <spa/defs.h>
typedef struct {
uint8_t *data;
size_t len;
off_t offset;
size_t len;
} SpaRingbufferArea;
/**
* SpaRingbuffer:
* @data: pointer to data
* @readindex: the current read index
* @writeindex: the current write index
* @size: the size of the ringbuffer
* @size_mask: mask if @size is power of 2
*/
struct _SpaRingbuffer {
uint8_t *data;
volatile size_t readindex;
volatile size_t writeindex;
size_t size;
@ -50,7 +48,7 @@ struct _SpaRingbuffer {
};
SpaResult spa_ringbuffer_init (SpaRingbuffer *rbuf,
uint8_t *data, size_t size);
size_t size);
SpaResult spa_ringbuffer_clear (SpaRingbuffer *rbuf);

View file

@ -492,7 +492,6 @@ spa_control_iter_set_data (SpaControlIter *iter,
size_t size)
{
struct stack_iter *si = SCSI (iter);
SpaResult res = SPA_RESULT_OK;
if (!is_valid_iter (iter))
return SPA_RESULT_INVALID_ARGUMENTS;
@ -526,12 +525,6 @@ spa_control_iter_parse_cmd (SpaControlIter *iter,
iter_parse_port_update (si, command);
break;
case SPA_CONTROL_CMD_PORT_REMOVED:
if (si->size < sizeof (SpaControlCmdPortRemoved))
return SPA_RESULT_ERROR;
memcpy (command, si->data, sizeof (SpaControlCmdPortRemoved));
break;
case SPA_CONTROL_CMD_PORT_STATUS_CHANGE:
fprintf (stderr, "implement iter of %d\n", si->cmd);
break;
@ -1245,11 +1238,6 @@ spa_control_builder_add_cmd (SpaControlBuilder *builder,
builder_add_port_update (sb, command);
break;
case SPA_CONTROL_CMD_PORT_REMOVED:
p = builder_add_cmd (sb, cmd, sizeof (SpaControlCmdPortRemoved));
memcpy (p, command, sizeof (SpaControlCmdPortRemoved));
break;
case SPA_CONTROL_CMD_PORT_STATUS_CHANGE:
p = builder_add_cmd (sb, cmd, 0);
break;

View file

@ -22,8 +22,8 @@
/**
* spa_ringbuffer_init:
* @rbuf: a #SpaRingbuffer
* @data: pointer to data
* @size: size of @data
* @data: pointer to an array
* @size: the number of elements in @data
*
* Initialize a #SpaRingbuffer with @data and @size.
* When size is a power of 2, size_mask will be set with the mask to
@ -34,12 +34,11 @@
*/
SpaResult
spa_ringbuffer_init (SpaRingbuffer *rbuf,
uint8_t *data, size_t size)
size_t size)
{
if (rbuf == NULL || data == NULL || size == 0)
if (rbuf == NULL || size == 0)
return SPA_RESULT_INVALID_ARGUMENTS;
rbuf->data = data;
rbuf->size = size;
rbuf->readindex = 0;
rbuf->writeindex = 0;
@ -93,13 +92,14 @@ spa_ringbuffer_get_read_areas (SpaRingbuffer *rbuf,
avail = (rbuf->size_mask ? avail & rbuf->size_mask : avail % rbuf->size);
}
end = r + avail;
areas[0].offset = r;
areas[1].offset = 0;
if (end > rbuf->size) {
areas[0].data = &rbuf->data[r];
areas[0].len = rbuf->size - r;
areas[1].data = rbuf->data;
areas[1].len = end - rbuf->size;
} else {
areas[0].data = &rbuf->data[r];
areas[0].len = avail;
areas[1].len = 0;
}
@ -146,20 +146,21 @@ spa_ringbuffer_get_write_areas (SpaRingbuffer *rbuf,
if (w > r) {
avail = (r - w + rbuf->size);
avail = (rbuf->size_mask ? avail & rbuf->size_mask : avail % rbuf->size);
avail -= 1;
} else if (w < r) {
avail = r - w - 1;
avail = r - w;
} else {
avail = rbuf->size - 1;
avail = rbuf->size;
}
avail -= 1;
end = w + avail;
areas[0].offset = w;
areas[1].offset = 0;
if (end > rbuf->size) {
areas[0].data = &rbuf->data[w];
areas[0].len = rbuf->size - w;
areas[1].data = rbuf->data;
areas[1].len = end - rbuf->size;
} else {
areas[0].data = &rbuf->data[w];
areas[0].len = avail;
areas[1].len = 0;
}

View file

@ -173,14 +173,11 @@ fill_item (ALSAItem *item, struct udev_device *udevice)
item->info_items[i].key = "device.product.id";
item->info_items[i++].value = str;
}
str = udev_device_get_property_value (item->udevice, "ID_V4L_PRODUCT");
str = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL_FROM_DATABASE");
str = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL_ENC");
if (!(str && *str)) {
str = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
str = udev_device_get_property_value (item->udevice, "ID_MODEL");
}
}
if (str && *str) {
@ -194,8 +191,8 @@ fill_item (ALSAItem *item, struct udev_device *udevice)
item->info_items[i].key = "device.serial";
item->info_items[i++].value = str;
}
if ((str = udev_device_get_property_value (item->udevice, "ID_V4L_CAPABILITIES")) && *str) {
item->info_items[i].key = "device.capabilities";
if ((str = udev_device_get_property_value (item->udevice, "SOUND_FORM_FACTOR")) && *str) {
item->info_items[i].key = "device.form_factor";
item->info_items[i++].value = str;
}
item->info.n_items = i;

View file

@ -338,9 +338,7 @@ static void
do_update_port (SpaProxy *this,
SpaControlCmdPortUpdate *pu)
{
SpaNodeEvent event;
SpaProxyPort *port;
SpaNodeEventPortAdded pa;
unsigned int i;
port = &this->ports[pu->port_id];
@ -369,12 +367,6 @@ do_update_port (SpaProxy *this,
this->n_inputs++;
else
this->n_outputs++;
event.type = SPA_NODE_EVENT_TYPE_PORT_ADDED;
event.size = sizeof (pa);
event.data = &pa;
pa.port_id = pu->port_id;
this->event_cb (&this->node, &event, this->user_data);
}
}
@ -382,9 +374,7 @@ static void
do_uninit_port (SpaProxy *this,
uint32_t port_id)
{
SpaNodeEvent event;
SpaProxyPort *port;
SpaNodeEventPortRemoved pr;
fprintf (stderr, "proxy %p: removing port %d\n", this, port_id);
port = &this->ports[port_id];
@ -398,12 +388,6 @@ do_uninit_port (SpaProxy *this,
if (port->format)
spa_format_unref (port->format);
port->format = NULL;
event.type = SPA_NODE_EVENT_TYPE_PORT_REMOVED;
event.size = sizeof (pr);
event.data = &pr;
pr.port_id = port_id;
this->event_cb (&this->node, &event, this->user_data);
}
static SpaResult
@ -934,8 +918,6 @@ handle_node_event (SpaProxy *this,
case SPA_NODE_EVENT_TYPE_INVALID:
break;
case SPA_NODE_EVENT_TYPE_PORT_ADDED:
case SPA_NODE_EVENT_TYPE_PORT_REMOVED:
case SPA_NODE_EVENT_TYPE_ASYNC_COMPLETE:
case SPA_NODE_EVENT_TYPE_HAVE_OUTPUT:
case SPA_NODE_EVENT_TYPE_NEED_INPUT:
@ -976,10 +958,6 @@ parse_control (SpaProxy *this,
fprintf (stderr, "proxy %p: got unexpected control %d\n", this, cmd);
break;
case SPA_CONTROL_CMD_PORT_REMOVED:
fprintf (stderr, "proxy %p: command not implemented %d\n", this, cmd);
break;
case SPA_CONTROL_CMD_NODE_UPDATE:
{
SpaControlCmdNodeUpdate nu;
@ -1045,12 +1023,11 @@ parse_control (SpaProxy *this,
if (spa_control_iter_parse_cmd (&it, &sc) < 0)
break;
fprintf (stderr, "proxy %p: got node state change %d -> %d\n", this, old, sc.state);
this->node.state = sc.state;
if (old == SPA_NODE_STATE_INIT)
send_async_complete (this, 0, SPA_RESULT_OK);
fprintf (stderr, "proxy %p: got node state change %d\n", this, this->node.state);
break;
}

View file

@ -28,6 +28,7 @@
#include <spa/memory.h>
#include <spa/video/format.h>
#include <spa/debug.h>
#include <spa/queue.h>
typedef struct _SpaV4l2Source SpaV4l2Source;
@ -105,8 +106,7 @@ typedef struct {
struct v4l2_requestbuffers reqbuf;
SpaMemory *alloc_mem;
V4l2Buffer *alloc_buffers;
V4l2Buffer *ready;
uint32_t ready_count;
SpaQueue ready;
SpaPollFd fds[1];
SpaPollItem poll;
@ -683,16 +683,13 @@ spa_v4l2_source_node_port_pull_output (SpaNode *node,
have_error = true;
continue;
}
if (state->ready_count == 0) {
SPA_QUEUE_POP_HEAD (&state->ready, V4l2Buffer, next, b);
if (b == NULL) {
info[i].status = SPA_RESULT_UNEXPECTED;
have_error = true;
continue;
}
b = state->ready;
state->ready = b->next;
state->ready_count--;
b->outstanding = true;
info[i].buffer_id = b->outbuf->id;
@ -844,6 +841,8 @@ v4l2_source_init (const SpaHandleFactory *factory,
this->props[1].props.prop_info = prop_info;
reset_v4l2_source_props (&this->props[1]);
SPA_QUEUE_INIT (&this->state[0].ready);
this->state[0].info.flags = SPA_PORT_INFO_FLAG_LIVE;
this->state[0].status.flags = SPA_PORT_STATUS_FLAG_NONE;

View file

@ -848,9 +848,7 @@ mmap_read (SpaV4l2Source *this)
d = SPA_BUFFER_DATAS (b->outbuf);
d[0].mem.size = buf.bytesused;
b->next = state->ready;
state->ready = b;
state->ready_count++;
SPA_QUEUE_PUSH_TAIL (&state->ready, V4l2Buffer, next, b);
return SPA_RESULT_OK;
}