work on port-update control message

Serialize format and properties.
Simplify the properties by moving the unset-mask inside the property
structure. We can then also just use the index of the property as the
bit in the mask.
Work on stopping on disconnect
This commit is contained in:
Wim Taymans 2016-08-08 22:10:57 +02:00
parent de53315f6e
commit 0d2f5a1386
24 changed files with 318 additions and 238 deletions

View file

@ -23,11 +23,16 @@ static SpaFormat *
format_copy (SpaFormat *format)
{
SpaMemory *mem;
SpaFormat *f;
if (format == NULL)
return NULL;
mem = spa_memory_alloc_size (format->mem.mem.pool_id, format, format->mem.size);
f = spa_memory_ensure_ptr (mem);
f->mem.mem = mem->mem;
f->mem.offset = 0;
f->mem.size = format->mem.size;
return spa_memory_ensure_ptr (mem);
}

View file

@ -864,6 +864,23 @@ unhandle_socket (PinosStream *stream)
}
}
typedef struct {
SpaProps props;
uint32_t unset_mask;
char target_node[64];
} PortProps;
static const SpaPropInfo port_props_info[] =
{
{ 0, "pinos.target.node", "The pinos target node",
SPA_PROP_FLAG_READWRITE,
SPA_PROP_TYPE_STRING, 64,
0, NULL,
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
NULL,
offsetof (PortProps, target_node) },
};
static void
do_node_init (PinosStream *stream)
{
@ -872,6 +889,7 @@ do_node_init (PinosStream *stream)
SpaControlCmdPortUpdate pu;
SpaControlBuilder builder;
SpaControl control;
PortProps port_props;
control_builder_init (stream, &builder);
nu.change_mask = SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS |
@ -881,6 +899,11 @@ do_node_init (PinosStream *stream)
nu.props = NULL;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu);
port_props.props.n_prop_info = SPA_N_ELEMENTS (port_props_info);
port_props.props.prop_info = port_props_info;
strncpy (port_props.target_node, priv->path, 64);
port_props.target_node[63] = '\0';
pu.port_id = 0;
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_DIRECTION |
SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
@ -889,7 +912,7 @@ do_node_init (PinosStream *stream)
pu.direction = priv->direction;
pu.n_possible_formats = priv->possible_formats->len;
pu.possible_formats = (const SpaFormat **)priv->possible_formats->pdata;
pu.props = NULL;
pu.props = &port_props.props;
pu.info = &priv->port_info;
priv->port_info.flags = SPA_PORT_INFO_FLAG_NONE |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
@ -1050,9 +1073,9 @@ pinos_stream_connect (PinosStream *stream,
priv->direction = direction;
g_free (priv->path);
priv->path = g_strdup (port_path);
priv->flags = flags;
if (priv->possible_formats)
g_ptr_array_unref (priv->possible_formats);
priv->flags = flags;
priv->possible_formats = possible_formats;
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);

View file

@ -42,8 +42,6 @@ main (gint argc, gchar *argv[])
props = pinos_properties_new ("test", "test", NULL);
daemon = pinos_daemon_new (props);
pinos_gst_manager_new (daemon);
factory = pinos_gst_node_factory_new ("gst-node-factory");
pinos_daemon_add_node_factory (daemon, factory);

View file

@ -55,7 +55,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
if (!gst_structure_get_int (cs, "height", &i))
goto done;
f->info.size.height = i;
f->unset_mask = 0;
f->format.props.unset_mask = 0;
res = &f->format;
} else if (gst_structure_has_name (cs, "audio/x-raw")) {
@ -81,7 +81,7 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
if (!gst_structure_get_int (cs, "channels", &i))
goto done;
f->info.channels = i;
f->unset_mask = 0;
f->format.props.unset_mask = 0;
res = &f->format;
}
@ -150,6 +150,7 @@ gst_caps_from_format (SpaFormat *format)
"format", G_TYPE_STRING, gst_video_format_to_string (f.info.format),
"width", G_TYPE_INT, f.info.size.width,
"height", G_TYPE_INT, f.info.size.height,
"framerate", GST_TYPE_FRACTION, f.info.framerate.num, f.info.framerate.denom,
NULL);
}
} else if (format->media_type == SPA_MEDIA_TYPE_AUDIO) {

View file

@ -290,7 +290,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
target = pinos_daemon_find_port (pinos_node_get_daemon (pnode),
pinos_direction_reverse (pa->direction),
"/org/pinos/node_8",
"/org/pinos/node_1",
NULL,
NULL,
&error);

View file

@ -182,6 +182,18 @@ no_node:
}
}
static void
on_port_added (PinosNode *node, PinosPort *port, PinosClient *client)
{
pinos_client_add_object (client, G_OBJECT (port));
}
static void
on_port_removed (PinosNode *node, PinosPort *port, PinosClient *client)
{
pinos_client_remove_object (client, G_OBJECT (port));
}
static gboolean
handle_create_client_node (PinosDaemon1 *interface,
GDBusMethodInvocation *invocation,
@ -216,6 +228,9 @@ handle_create_client_node (PinosDaemon1 *interface,
client = sender_get_client (daemon, sender);
pinos_client_add_object (client, G_OBJECT (node));
g_signal_connect (node, "port-added", (GCallback) on_port_added, client);
g_signal_connect (node, "port-removed", (GCallback) on_port_removed, client);
object_path = pinos_node_get_object_path (PINOS_NODE (node));
g_debug ("daemon %p: add client-node %p, %s", daemon, node, object_path);

View file

@ -174,13 +174,13 @@ pinos_link_set_property (GObject *_object,
break;
case PROP_OUTPUT:
priv->output = g_value_dup_object (value);
priv->output = g_value_get_object (value);
priv->output_node = priv->output->node->node;
priv->output_port = priv->output->id;
break;
case PROP_INPUT:
priv->input = g_value_dup_object (value);
priv->input = g_value_get_object (value);
priv->input_node = priv->input->node->node;
priv->input_port = priv->input->id;
break;
@ -277,7 +277,7 @@ do_negotiate (PinosLink *this)
value.type = SPA_PROP_TYPE_FRACTION;
value.size = sizeof (SpaFraction);
value.value = &frac;
frac.num = 25;
frac.num = 20;
frac.denom = 1;
if ((res = spa_props_set_prop (props, spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_FRAMERATE), &value)) < 0)
return res;
@ -334,12 +334,12 @@ on_activate (PinosPort *port, gpointer user_data)
if (priv->active)
return TRUE;
priv->active = TRUE;
if (priv->input == port)
pinos_port_activate (priv->output);
else
pinos_port_activate (priv->input);
priv->active = TRUE;
if (!priv->negotiated)
do_negotiate (this);
@ -367,12 +367,12 @@ on_deactivate (PinosPort *port, gpointer user_data)
if (!priv->active)
return TRUE;
priv->active = FALSE;
if (priv->input == port)
pinos_port_deactivate (priv->output);
else
pinos_port_deactivate (priv->input);
priv->active = FALSE;
cmd.type = SPA_COMMAND_STOP;
if ((res = spa_node_send_command (priv->input_node, &cmd)) < 0)

View file

@ -69,6 +69,8 @@ enum
enum
{
SIGNAL_REMOVE,
SIGNAL_PORT_ADDED,
SIGNAL_PORT_REMOVED,
LAST_SIGNAL
};
@ -105,6 +107,7 @@ node_add_port (PinosNode *node,
if (port) {
g_hash_table_insert (priv->ports, GUINT_TO_POINTER (id), port);
g_signal_connect (port, "remove", (GCallback) do_remove_port, node);
g_signal_emit (node, signals[SIGNAL_PORT_ADDED], 0, port);
}
return port;
}
@ -114,8 +117,14 @@ node_remove_port (PinosNode *node,
guint id)
{
PinosNodePrivate *priv = node->priv;
PinosPort *port;
g_debug ("node %p: removed port %u", node, id);
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id));
port = g_hash_table_lookup (priv->ports, GUINT_TO_POINTER (id));
if (port) {
g_signal_emit (node, signals[SIGNAL_PORT_REMOVED], 0, port);
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id));
}
return TRUE;
}
@ -497,6 +506,26 @@ pinos_node_class_init (PinosNodeClass * klass)
G_TYPE_NONE,
0,
G_TYPE_NONE);
signals[SIGNAL_PORT_ADDED] = g_signal_new ("port-added",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE,
0,
PINOS_TYPE_PORT);
signals[SIGNAL_PORT_REMOVED] = g_signal_new ("port-removed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
g_cclosure_marshal_generic,
G_TYPE_NONE,
0,
PINOS_TYPE_PORT);
node_class->set_state = node_set_state;
node_class->add_port = node_add_port;
@ -522,7 +551,10 @@ pinos_node_init (PinosNode * node)
priv->state = PINOS_NODE_STATE_SUSPENDED;
pinos_node1_set_state (priv->iface, PINOS_NODE_STATE_SUSPENDED);
priv->ports = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_object_unref);
priv->ports = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
(GDestroyNotify) g_object_unref);
}
/**

View file

@ -273,8 +273,11 @@ static void
pinos_port_dispose (GObject * object)
{
PinosPort *port = PINOS_PORT (object);
PinosPortPrivate *priv = port->priv;
g_debug ("port %p: dispose", port);
g_debug ("port %p: dispose %d", port, priv->active_count);
if (priv->active_count == 1)
g_signal_emit (port, signals[SIGNAL_DEACTIVATE], 0, NULL);
G_OBJECT_CLASS (pinos_port_parent_class)->dispose (object);
}
@ -437,7 +440,7 @@ pinos_port_class_init (PinosPortClass * klass)
static void
pinos_port_init (PinosPort * port)
{
PinosPortPrivate *priv = port->priv = PINOS_PORT_GET_PRIVATE (port);
port->priv = PINOS_PORT_GET_PRIVATE (port);
g_debug ("port %p: new", port);
port->direction = PINOS_DIRECTION_INVALID;