Remove direction

Direction is tied to the port id.
Handle nodes with fixed ports.
This commit is contained in:
Wim Taymans 2016-08-29 18:31:53 +02:00
parent 7d8e2d53f7
commit 9485bd77e7
25 changed files with 246 additions and 165 deletions

View file

@ -575,8 +575,6 @@ add_port_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang
pu.port_id = 0;
pu.change_mask = change_mask;
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION)
pu.direction = priv->direction;
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) {
pu.n_possible_formats = priv->possible_formats->len;
pu.possible_formats = (SpaFormat **)priv->possible_formats->pdata;
@ -1003,8 +1001,7 @@ on_node_proxy (GObject *source_object,
SPA_CONTROL_CMD_NODE_UPDATE_MAX_OUTPUTS);
priv->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
add_port_update (stream, &builder, SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION |
SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
add_port_update (stream, &builder, SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
SPA_CONTROL_CMD_PORT_UPDATE_INFO);
add_state_change (stream, &builder, SPA_NODE_STATE_CONFIGURE);

View file

@ -31,7 +31,6 @@
typedef struct {
PinosGstSink *sink;
guint id;
PinosPort *port;
GstElement *src;
@ -384,7 +383,6 @@ free_sink_port_data (SinkPortData *data)
static PinosPort *
add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
@ -394,9 +392,8 @@ add_port (PinosNode *node,
data = g_slice_new0 (SinkPortData);
data->sink = sink;
data->id = id;
data->port = PINOS_NODE_CLASS (pinos_gst_sink_parent_class)
->add_port (node, direction, id, error);
->add_port (node, id, error);
g_debug ("connecting signals");
g_signal_connect (data->port, "activate", (GCallback) on_activate, data);
@ -422,7 +419,7 @@ add_port (PinosNode *node,
static gboolean
remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
PinosGstSink *sink = PINOS_GST_SINK (node);
PinosGstSinkPrivate *priv = sink->priv;
@ -431,7 +428,7 @@ remove_port (PinosNode *node,
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SinkPortData *data = walk->data;
if (data->id == id) {
if (data->port == port) {
free_sink_port_data (data);
priv->ports = g_list_delete_link (priv->ports, walk);
break;

View file

@ -433,7 +433,7 @@ free_source_port_data (SourcePortData *data)
static gboolean
remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
PinosGstSource *source = PINOS_GST_SOURCE (node);
PinosGstSourcePrivate *priv = source->priv;
@ -442,7 +442,7 @@ remove_port (PinosNode *node,
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SourcePortData *data = walk->data;
if (data->id == id) {
if (data->port == port) {
free_source_port_data (data);
priv->ports = g_list_delete_link (priv->ports, walk);
break;
@ -552,7 +552,6 @@ create_best_element (GstCaps *caps)
static PinosPort *
add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
@ -577,9 +576,8 @@ add_port (PinosNode *node,
data = g_slice_new0 (SourcePortData);
data->source = source;
data->id = id;
data->port = PINOS_NODE_CLASS (pinos_gst_source_parent_class)
->add_port (node, direction, id, error);
->add_port (node, id, error);
g_debug ("connecting signals");
g_signal_connect (data->port, "activate", (GCallback) on_activate, data);

View file

@ -38,7 +38,6 @@
typedef struct {
PinosSpaAlsaSink *sink;
guint id;
PinosPort *port;
} SinkPortData;
@ -166,6 +165,7 @@ on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
PinosRingbufferArea areas[2];
uint8_t *data;
size_t size, towrite, total;
SpaEventNeedInput *ni = event->data;
size = 0;
data = NULL;
@ -186,7 +186,7 @@ on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
pinos_ringbuffer_read_advance (priv->ringbuffer, total);
iinfo.port_id = event->port_id;
iinfo.port_id = ni->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
iinfo.buffer_id = 0;
@ -417,7 +417,6 @@ on_received_event (PinosPort *port,
static PinosPort *
add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
@ -427,9 +426,8 @@ add_port (PinosNode *node,
data = g_slice_new0 (SinkPortData);
data->sink = sink;
data->id = id;
data->port = PINOS_NODE_CLASS (pinos_spa_alsa_sink_parent_class)
->add_port (node, direction, id, error);
->add_port (node, id, error);
pinos_port_set_received_cb (data->port, on_received_buffer, on_received_event, sink, NULL);
@ -444,7 +442,7 @@ add_port (PinosNode *node,
static gboolean
remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
PinosSpaAlsaSink *sink = PINOS_SPA_ALSA_SINK (node);
PinosSpaAlsaSinkPrivate *priv = sink->priv;
@ -453,7 +451,7 @@ remove_port (PinosNode *node,
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
SinkPortData *data = walk->data;
if (data->id == id) {
if (data->port == port) {
free_sink_port_data (data);
priv->ports = g_list_delete_link (priv->ports, walk);
break;

View file

@ -332,10 +332,10 @@ on_deactivate (PinosPort *port, gpointer user_data)
static gboolean
remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
return PINOS_NODE_CLASS (pinos_spa_v4l2_source_parent_class)
->remove_port (node, id);
->remove_port (node, port);
}
static void
@ -377,7 +377,7 @@ on_received_event (PinosPort *port, SpaEvent *event, GError **error, gpointer us
SpaEventReuseBuffer *rb = event->data;
if ((res = spa_node_port_reuse_buffer (node->node,
event->port_id,
rb->port_id,
rb->buffer_id)) < 0)
g_warning ("client-node %p: error reuse buffer: %d", node, res);
break;
@ -393,7 +393,6 @@ on_received_event (PinosPort *port, SpaEvent *event, GError **error, gpointer us
static PinosPort *
add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
@ -401,7 +400,7 @@ add_port (PinosNode *node,
PinosPort *port;
port = PINOS_NODE_CLASS (pinos_spa_v4l2_source_parent_class)
->add_port (node, direction, id, error);
->add_port (node, id, error);
pinos_port_set_received_cb (port, on_received_buffer, on_received_event, node, NULL);

View file

@ -273,8 +273,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
GError *error = NULL;
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (pnode,
pa->direction,
event->port_id,
pa->port_id,
&error);
if (port == NULL) {
@ -339,7 +338,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
if ((res = spa_node_port_pull_output (node, 1, info)) < 0)
g_debug ("client-node %p: got pull error %d, %d", this, res, info[0].status);
port = pinos_node_find_port (PINOS_NODE (this), info[0].port_id);
port = pinos_node_find_port_by_id (PINOS_NODE (this), info[0].port_id);
if (!pinos_port_send_buffer (port, info[0].buffer_id, &error)) {
g_debug ("send failed: %s", error->message);
@ -351,8 +350,9 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
{
PinosPort *port;
GError *error = NULL;
SpaEventReuseBuffer *rb = event->data;
port = pinos_node_find_port (PINOS_NODE (this), event->port_id);
port = pinos_node_find_port_by_id (PINOS_NODE (this), rb->port_id);
pinos_port_send_event (port, event, &error);
break;
}
@ -374,16 +374,15 @@ setup_node (PinosClientNode *this)
static PinosPort *
add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
PinosPort *port;
if (spa_node_add_port (node->node, direction, id) < 0)
if (spa_node_add_port (node->node, id) < 0)
g_warning ("client-node %p: error adding port", node);
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (node, direction, id, error);
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (node, id, error);
if (port) {
pinos_port_set_received_cb (port, on_received_buffer, on_received_event, node, NULL);
@ -393,12 +392,12 @@ add_port (PinosNode *node,
static gboolean
remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
if (spa_node_remove_port (node->node, id) < 0)
if (spa_node_remove_port (node->node, port->id) < 0)
g_warning ("client-node %p: error removing port", node);
return PINOS_NODE_CLASS (pinos_client_node_parent_class)->remove_port (node, id);
return PINOS_NODE_CLASS (pinos_client_node_parent_class)->remove_port (node, port);
}
static void

View file

@ -573,12 +573,22 @@ pinos_daemon_find_port (PinosDaemon *daemon,
}
}
if (best == NULL && node_found) {
g_debug ("node %p: making port", n);
best = pinos_node_add_port (n, direction, 0, NULL);
guint id;
id = pinos_node_get_free_port_id (n, direction);
if (id != SPA_ID_INVALID) {
g_debug ("node %p: making port with id %u", n, id);
best = pinos_node_add_port (n, id, NULL);
if (best != NULL) {
created_port = TRUE;
break;
}
} else {
g_debug ("node %p: using port with id %u", n, id);
best = pinos_node_find_port_by_id (n, id);
if (best != NULL)
break;
}
}
}
if (best == NULL) {

View file

@ -43,6 +43,13 @@ struct _PinosNodePrivate
gchar *object_path;
gchar *name;
unsigned int max_input_ports;
unsigned int max_output_ports;
unsigned int n_input_ports;
unsigned int n_output_ports;
uint32_t *input_port_ids;
uint32_t *output_port_ids;
PinosNodeState state;
GError *error;
guint idle_timeout;
@ -87,17 +94,53 @@ node_set_state (PinosNode *node,
static void
do_remove_port (PinosPort *port, PinosNode *node)
{
pinos_node_remove_port (node, port->id);
pinos_node_remove_port (node, port);
}
static void
update_port_ids (PinosNode *node, gboolean create)
{
PinosNodePrivate *priv = node->priv;
guint i;
if (node->node == NULL)
return;
spa_node_get_n_ports (node->node,
&priv->n_input_ports,
&priv->max_input_ports,
&priv->n_output_ports,
&priv->max_output_ports);
priv->input_port_ids = g_realloc_n (priv->input_port_ids, priv->max_input_ports, sizeof (uint32_t));
priv->output_port_ids = g_realloc_n (priv->output_port_ids, priv->max_output_ports, sizeof (uint32_t));
spa_node_get_port_ids (node->node,
priv->max_input_ports,
priv->input_port_ids,
priv->max_output_ports,
priv->output_port_ids);
if (create) {
for (i = 0; i < priv->n_input_ports; i++)
pinos_node_add_port (node, priv->input_port_ids[i], NULL);
for (i = 0; i < priv->n_output_ports; i++)
pinos_node_add_port (node, priv->output_port_ids[i], NULL);
}
}
static PinosPort *
node_add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
PinosNodePrivate *priv = node->priv;
PinosPort *port;
PinosDirection direction;
update_port_ids (node, FALSE);
direction = id < priv->max_input_ports ? PINOS_DIRECTION_INPUT : PINOS_DIRECTION_OUTPUT;
port = g_object_new (PINOS_TYPE_PORT,
"daemon", priv->daemon,
@ -115,17 +158,16 @@ node_add_port (PinosNode *node,
static gboolean
node_remove_port (PinosNode *node,
guint id)
PinosPort *port)
{
PinosNodePrivate *priv = node->priv;
PinosPort *port;
g_debug ("node %p: removed port %u", node, id);
port = g_hash_table_lookup (priv->ports, GUINT_TO_POINTER (id));
if (port) {
g_debug ("node %p: removed port %u", node, port->id);
g_object_ref (port);
if (g_hash_table_remove (priv->ports, GUINT_TO_POINTER (port->id)))
g_signal_emit (node, signals[SIGNAL_PORT_REMOVED], 0, port);
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id));
}
g_object_unref (port);
return TRUE;
}
@ -146,7 +188,7 @@ handle_add_port (PinosNode1 *interface,
if (g_strcmp0 (priv->sender, sender) != 0)
goto not_allowed;
port = pinos_node_add_port (node, arg_direction, arg_id, &error);
port = pinos_node_add_port (node, arg_id, &error);
if (port == NULL)
goto no_port;
@ -182,12 +224,17 @@ handle_remove_port (PinosNode1 *interface,
PinosNode *node = user_data;
PinosNodePrivate *priv = node->priv;
const gchar *sender;
PinosPort *port;
sender = g_dbus_method_invocation_get_sender (invocation);
if (g_strcmp0 (priv->sender, sender) != 0)
goto not_allowed;
if (!pinos_node_remove_port (node, arg_id))
port = pinos_node_find_port_by_id (node, arg_id);
if (port == NULL)
goto no_port;
if (!pinos_node_remove_port (node, port))
goto no_port;
g_debug ("node %p: remove port %u", node, arg_id);
@ -377,6 +424,8 @@ pinos_node_constructed (GObject * obj)
g_signal_connect (node, "notify", (GCallback) on_property_notify, node);
G_OBJECT_CLASS (pinos_node_parent_class)->constructed (obj);
update_port_ids (node, TRUE);
if (priv->sender == NULL) {
priv->sender = g_strdup (pinos_daemon_get_sender (priv->daemon));
}
@ -415,6 +464,8 @@ pinos_node_finalize (GObject * obj)
g_clear_error (&priv->error);
if (priv->properties)
pinos_properties_free (priv->properties);
g_free (priv->input_port_ids);
g_free (priv->output_port_ids);
G_OBJECT_CLASS (pinos_node_parent_class)->finalize (obj);
}
@ -743,7 +794,6 @@ pinos_node_remove (PinosNode *node)
*/
PinosPort *
pinos_node_add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error)
{
@ -759,7 +809,7 @@ pinos_node_add_port (PinosNode *node,
}
g_debug ("node %p: add port", node);
port = klass->add_port (node, direction, id, error);
port = klass->add_port (node, id, error);
return port;
}
@ -767,31 +817,75 @@ pinos_node_add_port (PinosNode *node,
/**
* pinos_node_remove_port:
* @node: a #PinosNode
* @id: a #PinosPort id
* @port: a #PinosPort
*
* Remove the #PinosPort with @id from @node
* Remove @port from @node
*
* Returns: %TRUE when the port was removed
*/
gboolean
pinos_node_remove_port (PinosNode *node, guint id)
pinos_node_remove_port (PinosNode *node, PinosPort *port)
{
PinosNodeClass *klass;
gboolean res = FALSE;
g_return_val_if_fail (PINOS_IS_NODE (node), FALSE);
g_return_val_if_fail (PINOS_IS_PORT (port), FALSE);
klass = PINOS_NODE_GET_CLASS (node);
if (!klass->remove_port)
return FALSE;
res = klass->remove_port (node, id);
res = klass->remove_port (node, port);
return res;
}
/**
* pinos_node_find_port:
* pinos_node_get_free_port_id:
* @node: a #PinosNode
* @direction: a #PinosDirection
*
* Find a new unused port id in @node with @direction
*
* Returns: the new port id of %SPA_INVALID_ID on error
*/
guint
pinos_node_get_free_port_id (PinosNode *node,
PinosDirection direction)
{
PinosNodePrivate *priv;
guint i, free_port = 0, n_ports, max_ports;
uint32_t *ports;
g_return_val_if_fail (PINOS_IS_NODE (node), -1);
priv = node->priv;
if (direction == PINOS_DIRECTION_INPUT) {
max_ports = priv->max_input_ports;
n_ports = priv->n_input_ports;
ports = priv->input_port_ids;
} else {
max_ports = priv->max_output_ports;
n_ports = priv->n_output_ports;
ports = priv->output_port_ids;
}
g_debug ("direction %d max %u, n %u\n", direction, max_ports, n_ports);
for (i = 0; i < n_ports; i++) {
if (free_port < ports[i])
break;
free_port = ports[i] + 1;
}
if (free_port >= max_ports)
return -1;
return free_port;
}
/**
* pinos_node_find_port_by_id:
* @node: a #PinosNode
* @id: a #PinosPort id
*
@ -800,7 +894,7 @@ pinos_node_remove_port (PinosNode *node, guint id)
* Returns: a #PinosPort with @id or %NULL when not found
*/
PinosPort *
pinos_node_find_port (PinosNode *node, guint id)
pinos_node_find_port_by_id (PinosNode *node, guint id)
{
PinosNodePrivate *priv;
@ -989,5 +1083,9 @@ pinos_node_update_node_state (PinosNode *node,
g_debug ("node %p: update SPA state to %d", node, state);
node->node_state = state;
g_object_notify (G_OBJECT (node), "node-state");
if (state == SPA_NODE_STATE_CONFIGURE) {
update_port_ids (node, FALSE);
}
}
}

View file

@ -70,11 +70,10 @@ struct _PinosNodeClass {
PinosNodeState state);
PinosPort * (*add_port) (PinosNode *node,
PinosDirection direction,
guint id,
GError **error);
gboolean (*remove_port) (PinosNode *node,
guint id);
PinosPort *port);
};
/* normal GObject stuff */
@ -94,13 +93,14 @@ PinosDaemon * pinos_node_get_daemon (PinosNode *node);
const gchar * pinos_node_get_sender (PinosNode *node);
const gchar * pinos_node_get_object_path (PinosNode *node);
guint pinos_node_get_free_port_id (PinosNode *node,
PinosDirection direction);
PinosPort * pinos_node_add_port (PinosNode *node,
PinosDirection direction,
guint id,
GError **error);
gboolean pinos_node_remove_port (PinosNode *node,
guint id);
PinosPort * pinos_node_find_port (PinosNode *node,
PinosPort *port);
PinosPort * pinos_node_find_port_by_id (PinosNode *node,
guint id);
GList * pinos_node_get_ports (PinosNode *node);

View file

@ -103,17 +103,15 @@ typedef struct {
typedef struct {
uint32_t port_id;
uint32_t change_mask;
SpaDirection direction;
unsigned int n_possible_formats;
SpaFormat **possible_formats;
const SpaProps *props;
const SpaPortInfo *info;
} SpaControlCmdPortUpdate;
#define SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION (1 << 0)
#define SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS (1 << 1)
#define SPA_CONTROL_CMD_PORT_UPDATE_PROPS (1 << 2)
#define SPA_CONTROL_CMD_PORT_UPDATE_INFO (1 << 3)
#define SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
#define SPA_CONTROL_CMD_PORT_UPDATE_PROPS (1 << 1)
#define SPA_CONTROL_CMD_PORT_UPDATE_INFO (1 << 2)
/* SPA_CONTROL_CMD_PORT_REMOVED */
typedef struct {
@ -141,7 +139,6 @@ typedef struct {
/* SPA_CONTROL_CMD_ADD_PORT */
typedef struct {
uint32_t port_id;
SpaDirection direction;
} SpaControlCmdAddPort;
/* SPA_CONTROL_CMD_REMOVE_PORT */

View file

@ -61,12 +61,6 @@ typedef enum {
SPA_RESULT_WRONG_STATE = -29,
} SpaResult;
typedef enum {
SPA_DIRECTION_INVALID = 0,
SPA_DIRECTION_INPUT,
SPA_DIRECTION_OUTPUT
} SpaDirection;
typedef void (*SpaNotify) (void *data);
#define SPA_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))

View file

@ -66,20 +66,32 @@ typedef enum {
struct _SpaEvent {
SpaEventType type;
uint32_t port_id;
void *data;
size_t size;
};
typedef struct {
SpaDirection direction;
uint32_t port_id;
} SpaEventPortAdded;
typedef struct {
uint32_t port_id;
} SpaEventPortRemoved;
typedef struct {
SpaNodeState state;
} SpaEventStateChange;
typedef struct {
uint32_t port_id;
} SpaEventHaveOutput;
typedef struct {
uint32_t port_id;
} SpaEventNeedInput;
typedef struct {
uint32_t port_id;
uint32_t buffer_id;
} SpaEventReuseBuffer;

View file

@ -267,8 +267,22 @@ struct _SpaNode {
unsigned int n_output_ports,
uint32_t *output_ids);
/**
* SpaNode::add_port:
* @node: a #SpaNode
* @port_id: an unused port id
*
* Make a new port with @port_id. The called should use get_port_ids() to
* find an unused id.
*
* Input port ids should be between 0 and max_input_ports and output ports
* between max_input_ports and max_input_ports + max_output_ports as obtained
* from get_port_ids().
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
SpaResult (*add_port) (SpaNode *node,
SpaDirection direction,
uint32_t port_id);
SpaResult (*remove_port) (SpaNode *node,
uint32_t port_id);

View file

@ -225,7 +225,6 @@ spa_alsa_sink_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -241,7 +240,6 @@ spa_alsa_sink_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -316,7 +314,6 @@ spa_alsa_sink_node_get_port_ids (SpaNode *node,
static SpaResult
spa_alsa_sink_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;

View file

@ -225,11 +225,12 @@ static void
pull_input (SpaALSASink *this, void *data, snd_pcm_uframes_t frames)
{
SpaEvent event;
SpaEventNeedInput ni;
event.type = SPA_EVENT_TYPE_NEED_INPUT;
event.port_id = 0;
event.size = 0;
event.data = NULL;
event.size = sizeof (ni);
event.data = &ni;
ni.port_id = 0;
this->event_cb (&this->node, &event, this->user_data);
}
@ -344,7 +345,6 @@ spa_alsa_start (SpaALSASink *this)
}
event.type = SPA_EVENT_TYPE_ADD_POLL;
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
@ -373,7 +373,6 @@ spa_alsa_stop (SpaALSASink *this)
snd_pcm_drop (state->handle);
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
this->event_cb (&this->node, &event, this->user_data);

View file

@ -152,7 +152,6 @@ spa_audiomixer_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -167,7 +166,6 @@ spa_audiomixer_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -253,7 +251,6 @@ spa_audiomixer_node_get_port_ids (SpaNode *node,
static SpaResult
spa_audiomixer_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaAudioMixer *this;
@ -263,9 +260,6 @@ spa_audiomixer_node_add_port (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (direction != SPA_DIRECTION_INPUT)
return SPA_RESULT_INVALID_DIRECTION;
if (port_id >= MAX_PORTS)
return SPA_RESULT_INVALID_PORT;
@ -571,11 +565,12 @@ static void
pull_port (SpaAudioMixer *this, uint32_t port_id, SpaOutputInfo *info, size_t pull_size)
{
SpaEvent event;
SpaEventNeedInput ni;
event.type = SPA_EVENT_TYPE_NEED_INPUT;
event.port_id = port_id;
event.size = 0;
event.data = NULL;
event.size = sizeof (ni);
event.data = &ni;
ni.port_id = port_id;
this->event_cb (&this->node, &event, this->user_data);
}

View file

@ -173,7 +173,6 @@ spa_audiotestsrc_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -188,7 +187,6 @@ spa_audiotestsrc_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -263,7 +261,6 @@ spa_audiotestsrc_node_get_port_ids (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;

View file

@ -148,7 +148,6 @@ spa_ffmpeg_dec_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -162,7 +161,6 @@ spa_ffmpeg_dec_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -240,7 +238,6 @@ spa_ffmpeg_dec_node_get_port_ids (SpaNode *node,
static SpaResult
spa_ffmpeg_dec_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;

View file

@ -148,7 +148,6 @@ spa_ffmpeg_enc_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -162,7 +161,6 @@ spa_ffmpeg_enc_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -240,7 +238,6 @@ spa_ffmpeg_enc_node_get_port_ids (SpaNode *node,
static SpaResult
spa_ffmpeg_enc_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;

View file

@ -39,7 +39,8 @@
#define CHECK_FREE_PORT_ID(this,id) ((id) < MAX_PORTS && !(this)->ports[id].valid)
#define CHECK_PORT_ID(this,id) ((id) < MAX_PORTS && (this)->ports[id].valid)
#define CHECK_PORT_ID_DIR(this,id,dir) (CHECK_PORT_ID(this,id) && (this)->ports[i].direction == (dir))
#define CHECK_PORT_ID_IN(this,id) (CHECK_PORT_ID(this,id) && (id < this->max_inputs))
#define CHECK_PORT_ID_OUT(this,id) (CHECK_PORT_ID(this,id) && (id >= this->max_inputs))
typedef struct _SpaProxy SpaProxy;
@ -50,7 +51,6 @@ typedef struct {
typedef struct {
bool valid;
SpaDirection direction;
SpaPortInfo info;
SpaFormat *format;
unsigned int n_formats;
@ -112,7 +112,6 @@ update_poll (SpaProxy *this, int socketfd)
if (p->socketfd != -1) {
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
event.port_id = 0;
event.data = &this->poll;
event.size = sizeof (this->poll);
this->event_cb (&this->node, &event, this->user_data);
@ -122,7 +121,6 @@ update_poll (SpaProxy *this, int socketfd)
if (p->socketfd != -1) {
this->fds[0].fd = p->socketfd;
event.type = SPA_EVENT_TYPE_ADD_POLL;
event.port_id = 0;
event.data = &this->poll;
event.size = sizeof (this->poll);
this->event_cb (&this->node, &event, this->user_data);
@ -139,7 +137,6 @@ update_state (SpaProxy *this, SpaNodeState state)
this->state = state;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = state;
@ -318,17 +315,15 @@ spa_proxy_node_get_port_ids (SpaNode *node,
this = (SpaProxy *) node->handle;
if (input_ids) {
n_input_ports = SPA_MIN (n_input_ports, MAX_PORTS);
for (c = 0, i = 0; i < n_input_ports; i++) {
if (this->ports[i].valid && this->ports[i].direction == SPA_DIRECTION_INPUT)
for (c = 0, i = 0; i < MAX_INPUTS && c < n_input_ports; i++) {
if (this->ports[i].valid)
input_ids[c++] = i;
}
}
if (output_ids) {
n_output_ports = SPA_MIN (n_output_ports, MAX_PORTS);
for (c = 0, i = 0; i < n_output_ports; i++) {
if (this->ports[i].valid && this->ports[i].direction == SPA_DIRECTION_OUTPUT)
output_ids[c++] = i;
for (c = 0, i = 0; i < MAX_OUTPUTS && c < n_output_ports; i++) {
if (this->ports[MAX_INPUTS + i].valid)
output_ids[c++] = MAX_INPUTS + i;
}
}
return SPA_RESULT_OK;
@ -361,21 +356,19 @@ do_update_port (SpaProxy *this,
}
if (!port->valid) {
fprintf (stderr, "%p: adding port %d, %d\n", this, pu->port_id, pu->direction);
port->direction = pu->direction;
fprintf (stderr, "%p: adding port %d\n", this, pu->port_id);
port->format = NULL;
port->valid = true;
if (pu->direction == SPA_DIRECTION_INPUT)
if (pu->port_id < MAX_INPUTS)
this->n_inputs++;
else
this->n_outputs++;
event.type = SPA_EVENT_TYPE_PORT_ADDED;
event.port_id = pu->port_id;
event.data = &pa;
event.size = sizeof (pa);
pa.direction = pu->direction;
event.data = &pa;
pa.port_id = pu->port_id;
this->event_cb (&this->node, &event, this->user_data);
}
}
@ -386,31 +379,30 @@ do_uninit_port (SpaProxy *this,
{
SpaEvent event;
SpaProxyPort *port;
SpaEventPortRemoved pr;
fprintf (stderr, "%p: removing port %d\n", this, port_id);
port = &this->ports[port_id];
if (port->direction == SPA_DIRECTION_INPUT)
if (port_id < MAX_INPUTS)
this->n_inputs--;
else
this->n_outputs--;
port->direction = SPA_DIRECTION_INVALID;
port->valid = false;
if (port->format)
spa_format_unref (port->format);
port->format = NULL;
event.type = SPA_EVENT_TYPE_PORT_REMOVED;
event.port_id = port_id;
event.data = NULL;
event.size = 0;
event.size = sizeof (pr);
event.data = &pr;
pr.port_id = port_id;
this->event_cb (&this->node, &event, this->user_data);
}
static SpaResult
spa_proxy_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaProxy *this;
@ -424,12 +416,10 @@ spa_proxy_node_add_port (SpaNode *node,
if (!CHECK_FREE_PORT_ID (this, port_id))
return SPA_RESULT_INVALID_PORT;
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION |
SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
SPA_CONTROL_CMD_PORT_UPDATE_PROPS |
SPA_CONTROL_CMD_PORT_UPDATE_INFO;
pu.port_id = port_id;
pu.direction = direction;
pu.n_possible_formats = 0;
pu.possible_formats = NULL;
pu.props = NULL;
@ -793,7 +783,7 @@ spa_proxy_node_port_push_input (SpaNode *node,
spa_control_builder_init_into (&builder, buf, sizeof(buf), NULL, 0);
for (i = 0; i < n_info; i++) {
if (!CHECK_PORT_ID_DIR (this, info[i].port_id, SPA_DIRECTION_INPUT)) {
if (!CHECK_PORT_ID_IN (this, info[i].port_id)) {
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
@ -852,7 +842,7 @@ spa_proxy_node_port_pull_output (SpaNode *node,
this = (SpaProxy *) node->handle;
for (i = 0; i < n_info; i++) {
if (!CHECK_PORT_ID_DIR (this, info[i].port_id, SPA_DIRECTION_OUTPUT)) {
if (!CHECK_PORT_ID_OUT (this, info[i].port_id)) {
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
@ -901,7 +891,7 @@ spa_proxy_node_port_push_event (SpaNode *node,
/* send start */
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
crb.port_id = event->port_id;
crb.port_id = rb->port_id;
crb.buffer_id = rb->buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_REUSE_BUFFER, &crb);
spa_control_builder_end (&builder, &control);
@ -946,12 +936,13 @@ parse_control (SpaProxy *this,
{
SpaControlCmdNodeUpdate nu;
fprintf (stderr, "proxy %p: got node update %d\n", this, cmd);
if (spa_control_iter_parse_cmd (&it, &nu) < 0)
break;
this->max_inputs = nu.max_input_ports;
this->max_outputs = nu.max_output_ports;
fprintf (stderr, "proxy %p: got node update %d, %u, %u\n", this, cmd,
this->max_inputs, this->max_outputs);
break;
}
@ -967,8 +958,7 @@ parse_control (SpaProxy *this,
if (pu.port_id >= MAX_PORTS)
break;
remove = (pu.change_mask & SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION) &&
(pu.direction == SPA_DIRECTION_INVALID);
remove = (pu.change_mask == 0);
if (remove) {
do_uninit_port (this, pu.port_id);
@ -1001,15 +991,16 @@ parse_control (SpaProxy *this,
case SPA_CONTROL_CMD_HAVE_OUTPUT:
{
SpaEvent event;
SpaEventHaveOutput hu;
SpaControlCmdHaveOutput cmd;
if (spa_control_iter_parse_cmd (&it, &cmd) < 0)
break;
event.type = SPA_EVENT_TYPE_HAVE_OUTPUT;
event.port_id = cmd.port_id;
event.data = NULL;
event.size = 0;
event.data = &hu;
event.size = sizeof (hu);
hu.port_id = cmd.port_id;
this->event_cb (&this->node, &event, this->user_data);
break;
}
@ -1043,9 +1034,9 @@ parse_control (SpaProxy *this,
break;
event.type = SPA_EVENT_TYPE_REUSE_BUFFER;
event.port_id = crb.port_id;
event.data = &rb;
event.size = sizeof (rb);
rb.port_id = crb.port_id;
rb.buffer_id = crb.buffer_id;
this->event_cb (&this->node, &event, this->user_data);

View file

@ -213,7 +213,6 @@ update_state (SpaV4l2Source *this, SpaNodeState state)
this->node_state = state;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = state;
@ -309,10 +308,10 @@ spa_v4l2_source_node_get_n_ports (SpaNode *node,
if (n_input_ports)
*n_input_ports = 0;
if (n_output_ports)
*n_output_ports = 1;
if (max_input_ports)
*max_input_ports = 0;
if (n_output_ports)
*n_output_ports = 1;
if (max_output_ports)
*max_output_ports = 1;
@ -338,7 +337,6 @@ spa_v4l2_source_node_get_port_ids (SpaNode *node,
static SpaResult
spa_v4l2_source_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -383,6 +381,8 @@ spa_v4l2_source_node_port_enum_formats (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
fprintf (stderr, "%d\n", port_id);
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;

View file

@ -583,14 +583,15 @@ v4l2_on_fd_events (SpaPollNotifyData *data)
{
SpaV4l2Source *this = data->user_data;
SpaEvent event;
SpaEventHaveOutput ho;
if (mmap_read (this) < 0)
return 0;
event.type = SPA_EVENT_TYPE_HAVE_OUTPUT;
event.port_id = 0;
event.size = 0;
event.data = NULL;
event.size = sizeof (ho);
event.data = &ho;
ho.port_id = 0;
this->event_cb (&this->node, &event, this->user_data);
return 0;
@ -856,7 +857,6 @@ spa_v4l2_start (SpaV4l2Source *this)
}
event.type = SPA_EVENT_TYPE_ADD_POLL;
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
@ -884,7 +884,6 @@ spa_v4l2_pause (SpaV4l2Source *this)
SpaEvent event;
event.type = SPA_EVENT_TYPE_REMOVE_POLL;
event.port_id = 0;
event.data = &state->poll;
event.size = sizeof (state->poll);
this->event_cb (&this->node, &event, this->user_data);

View file

@ -157,7 +157,6 @@ spa_volume_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -172,7 +171,6 @@ spa_volume_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -250,7 +248,6 @@ spa_volume_node_get_port_ids (SpaNode *node,
static SpaResult
spa_volume_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -524,9 +521,9 @@ release_buffer (SpaVolume *this, SpaBuffer *buffer)
SpaEventReuseBuffer rb;
event.type = SPA_EVENT_TYPE_REUSE_BUFFER;
event.port_id = 0;
event.data = &rb;
event.size = sizeof (rb);
rb.port_id = 0;
rb.buffer_id = buffer->id;
this->event_cb (&this->node, &event, this->user_data);
}

View file

@ -181,7 +181,6 @@ spa_xv_sink_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
@ -197,7 +196,6 @@ spa_xv_sink_node_send_command (SpaNode *node,
SpaEventStateChange sc;
event.type = SPA_EVENT_TYPE_STATE_CHANGE;
event.port_id = -1;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
@ -273,7 +271,6 @@ spa_xv_sink_node_get_port_ids (SpaNode *node,
static SpaResult
spa_xv_sink_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;

View file

@ -99,11 +99,12 @@ on_mix_event (SpaNode *node, SpaEvent *event, void *user_data)
SpaInputInfo iinfo;
SpaOutputInfo oinfo;
SpaResult res;
SpaEventNeedInput *ni = event->data;
oinfo.port_id = 0;
oinfo.flags = SPA_OUTPUT_FLAG_NONE;
if (event->port_id == data->mix_ports[0]) {
if (ni->port_id == data->mix_ports[0]) {
if ((res = spa_node_port_pull_output (data->source1, 1, &oinfo)) < 0)
printf ("got error %d\n", res);
} else {
@ -111,7 +112,7 @@ on_mix_event (SpaNode *node, SpaEvent *event, void *user_data)
printf ("got error %d\n", res);
}
iinfo.port_id = event->port_id;
iinfo.port_id = ni->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
iinfo.buffer_id = oinfo.buffer_id;
@ -136,6 +137,7 @@ on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
SpaInputInfo iinfo;
SpaOutputInfo oinfo;
SpaResult res;
SpaEventNeedInput *ni = event->data;
oinfo.port_id = 0;
oinfo.flags = SPA_OUTPUT_FLAG_PULL;
@ -143,7 +145,7 @@ on_sink_event (SpaNode *node, SpaEvent *event, void *user_data)
if ((res = spa_node_port_pull_output (data->mix, 1, &oinfo)) < 0)
printf ("got error %d\n", res);
iinfo.port_id = event->port_id;
iinfo.port_id = ni->port_id;
iinfo.flags = SPA_INPUT_FLAG_NONE;
iinfo.buffer_id = oinfo.buffer_id;
@ -251,7 +253,7 @@ negotiate_formats (AppData *data)
return res;
data->mix_ports[0] = 0;
if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 0)) < 0)
if ((res = spa_node_add_port (data->mix, 0)) < 0)
return res;
if ((res = spa_node_port_set_format (data->mix, data->mix_ports[0], false, format)) < 0)
@ -261,7 +263,7 @@ negotiate_formats (AppData *data)
return res;
data->mix_ports[1] = 0;
if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 1)) < 0)
if ((res = spa_node_add_port (data->mix, 1)) < 0)
return res;
if ((res = spa_node_port_set_format (data->mix, data->mix_ports[1], false, format)) < 0)