mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-22 06:59:59 -05:00
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:
parent
de53315f6e
commit
0d2f5a1386
24 changed files with 318 additions and 238 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue