mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-20 06:59:58 -05:00
Fix upload mode
Add autoconnect property to the ports Remove the upload-node, clients that want to upload media just create a node with an (unconnected) output port. Other clients can then connect to this new output port. Copy formats on newly linked ports.
This commit is contained in:
parent
6108487d4e
commit
323b0c55f2
11 changed files with 205 additions and 608 deletions
|
|
@ -358,105 +358,32 @@ no_format:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_link:
|
||||
* @source: a source #PinosPort
|
||||
* @destination: a destination #PinosPort
|
||||
*
|
||||
* Link two ports together.
|
||||
*
|
||||
* Returns: %TRUE if ports could be linked.
|
||||
*/
|
||||
gboolean
|
||||
pinos_port_link (PinosPort *source, PinosPort *destination)
|
||||
{
|
||||
g_return_val_if_fail (PINOS_IS_PORT (source), FALSE);
|
||||
g_return_val_if_fail (PINOS_IS_PORT (destination), FALSE);
|
||||
g_return_val_if_fail (source->priv->direction != destination->priv->direction, FALSE);
|
||||
|
||||
if (source->priv->direction != PINOS_DIRECTION_OUTPUT) {
|
||||
PinosPort *tmp;
|
||||
tmp = source;
|
||||
source = destination;
|
||||
destination = tmp;
|
||||
}
|
||||
|
||||
source->priv->peers[source->priv->n_peers++] = destination;
|
||||
destination->priv->peers[destination->priv->n_peers++] = source;
|
||||
|
||||
g_debug ("port %p: linked to %p", source, destination);
|
||||
g_signal_emit (source, signals[SIGNAL_LINKED], 0, destination);
|
||||
g_signal_emit (destination, signals[SIGNAL_LINKED], 0, source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_unlink:
|
||||
* @source: a source #PinosPort
|
||||
* @destination: a destination #PinosPort
|
||||
*
|
||||
* Link two ports together.
|
||||
*
|
||||
* Returns: %TRUE if ports could be linked.
|
||||
*/
|
||||
gboolean
|
||||
pinos_port_unlink (PinosPort *source, PinosPort *destination)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (PINOS_IS_PORT (source), FALSE);
|
||||
g_return_val_if_fail (PINOS_IS_PORT (destination), FALSE);
|
||||
|
||||
for (i = 0; i < source->priv->n_peers; i++) {
|
||||
if (source->priv->peers[i] == destination)
|
||||
source->priv->peers[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < destination->priv->n_peers; i++) {
|
||||
if (destination->priv->peers[i] == source)
|
||||
destination->priv->peers[i] = NULL;
|
||||
}
|
||||
|
||||
g_debug ("port %p: unlinked from %p", source, destination);
|
||||
g_signal_emit (source, signals[SIGNAL_UNLINKED], 0, destination);
|
||||
g_signal_emit (destination, signals[SIGNAL_UNLINKED], 0, source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pinos_port_unlink_all (PinosPort *port)
|
||||
parse_control_buffer (PinosPort *port, PinosBuffer *buffer)
|
||||
{
|
||||
gint i;
|
||||
PinosPortPrivate *priv = port->priv;
|
||||
PinosBufferIter it;
|
||||
|
||||
for (i = 0; i < port->priv->n_peers; i++) {
|
||||
PinosPort *peer = port->priv->peers[i];
|
||||
if (peer == NULL)
|
||||
continue;
|
||||
if (peer->priv->peers[i] == port)
|
||||
peer->priv->peers[i] = NULL;
|
||||
port->priv->peers[i] = NULL;
|
||||
peer->priv->n_peers--;
|
||||
g_signal_emit (port, signals[SIGNAL_UNLINKED], 0, peer);
|
||||
g_signal_emit (peer, signals[SIGNAL_UNLINKED], 0, port);
|
||||
pinos_buffer_iter_init (&it, buffer);
|
||||
while (pinos_buffer_iter_next (&it)) {
|
||||
switch (pinos_buffer_iter_get_type (&it)) {
|
||||
case PINOS_PACKET_TYPE_FORMAT_CHANGE:
|
||||
{
|
||||
PinosPacketFormatChange change;
|
||||
|
||||
if (!pinos_buffer_iter_parse_format_change (&it, &change))
|
||||
continue;
|
||||
|
||||
if (priv->format)
|
||||
g_bytes_unref (priv->format);
|
||||
priv->format = g_bytes_new (change.format, strlen (change.format) + 1);
|
||||
g_object_notify (G_OBJECT (port), "format");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
port->priv->n_peers = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_get_n_links:
|
||||
* @port: a #PinosPort
|
||||
*
|
||||
* Get the number of links on this port
|
||||
*
|
||||
* Returns: the number of links
|
||||
*/
|
||||
gint
|
||||
pinos_port_get_n_links (PinosPort *port)
|
||||
{
|
||||
g_return_val_if_fail (PINOS_IS_PORT (port), -1);
|
||||
|
||||
return port->priv->n_peers;
|
||||
}
|
||||
|
||||
static PinosBuffer *
|
||||
|
|
@ -611,33 +538,6 @@ send_error:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_control_buffer (PinosPort *port, PinosBuffer *buffer)
|
||||
{
|
||||
PinosPortPrivate *priv = port->priv;
|
||||
PinosBufferIter it;
|
||||
|
||||
pinos_buffer_iter_init (&it, buffer);
|
||||
while (pinos_buffer_iter_next (&it)) {
|
||||
switch (pinos_buffer_iter_get_type (&it)) {
|
||||
case PINOS_PACKET_TYPE_FORMAT_CHANGE:
|
||||
{
|
||||
PinosPacketFormatChange change;
|
||||
|
||||
if (!pinos_buffer_iter_parse_format_change (&it, &change))
|
||||
continue;
|
||||
|
||||
if (priv->format)
|
||||
g_bytes_unref (priv->format);
|
||||
priv->format = g_bytes_new (change.format, strlen (change.format) + 1);
|
||||
g_object_notify (G_OBJECT (port), "format");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pinos_port_receive_buffer (PinosPort *port,
|
||||
|
|
@ -679,6 +579,127 @@ buffer_queued:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_link:
|
||||
* @source: a source #PinosPort
|
||||
* @destination: a destination #PinosPort
|
||||
*
|
||||
* Link two ports together.
|
||||
*
|
||||
* Returns: %TRUE if ports could be linked.
|
||||
*/
|
||||
gboolean
|
||||
pinos_port_link (PinosPort *source, PinosPort *destination)
|
||||
{
|
||||
g_return_val_if_fail (PINOS_IS_PORT (source), FALSE);
|
||||
g_return_val_if_fail (PINOS_IS_PORT (destination), FALSE);
|
||||
g_return_val_if_fail (source->priv->direction != destination->priv->direction, FALSE);
|
||||
|
||||
if (source->priv->direction != PINOS_DIRECTION_OUTPUT) {
|
||||
PinosPort *tmp;
|
||||
tmp = source;
|
||||
source = destination;
|
||||
destination = tmp;
|
||||
}
|
||||
|
||||
source->priv->peers[source->priv->n_peers++] = destination;
|
||||
destination->priv->peers[destination->priv->n_peers++] = source;
|
||||
|
||||
if (source->priv->format) {
|
||||
PinosBufferBuilder builder;
|
||||
PinosBuffer pbuf;
|
||||
PinosPacketFormatChange fc;
|
||||
GError *error = NULL;
|
||||
|
||||
pinos_port_buffer_builder_init (destination, &builder);
|
||||
fc.id = 0;
|
||||
fc.format = g_bytes_get_data (source->priv->format, NULL);
|
||||
pinos_buffer_builder_add_format_change (&builder, &fc);
|
||||
pinos_buffer_builder_end (&builder, &pbuf);
|
||||
|
||||
if (!pinos_port_receive_buffer (destination, &pbuf, &error)) {
|
||||
g_warning ("port %p: counld not receive format: %s", destination, error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
pinos_buffer_unref (&pbuf);
|
||||
}
|
||||
|
||||
|
||||
g_debug ("port %p: linked to %p", source, destination);
|
||||
g_signal_emit (source, signals[SIGNAL_LINKED], 0, destination);
|
||||
g_signal_emit (destination, signals[SIGNAL_LINKED], 0, source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_unlink:
|
||||
* @source: a source #PinosPort
|
||||
* @destination: a destination #PinosPort
|
||||
*
|
||||
* Link two ports together.
|
||||
*
|
||||
* Returns: %TRUE if ports could be linked.
|
||||
*/
|
||||
gboolean
|
||||
pinos_port_unlink (PinosPort *source, PinosPort *destination)
|
||||
{
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (PINOS_IS_PORT (source), FALSE);
|
||||
g_return_val_if_fail (PINOS_IS_PORT (destination), FALSE);
|
||||
|
||||
for (i = 0; i < source->priv->n_peers; i++) {
|
||||
if (source->priv->peers[i] == destination)
|
||||
source->priv->peers[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < destination->priv->n_peers; i++) {
|
||||
if (destination->priv->peers[i] == source)
|
||||
destination->priv->peers[i] = NULL;
|
||||
}
|
||||
|
||||
g_debug ("port %p: unlinked from %p", source, destination);
|
||||
g_signal_emit (source, signals[SIGNAL_UNLINKED], 0, destination);
|
||||
g_signal_emit (destination, signals[SIGNAL_UNLINKED], 0, source);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pinos_port_unlink_all (PinosPort *port)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < port->priv->n_peers; i++) {
|
||||
PinosPort *peer = port->priv->peers[i];
|
||||
if (peer == NULL)
|
||||
continue;
|
||||
if (peer->priv->peers[i] == port)
|
||||
peer->priv->peers[i] = NULL;
|
||||
port->priv->peers[i] = NULL;
|
||||
peer->priv->n_peers--;
|
||||
g_signal_emit (port, signals[SIGNAL_UNLINKED], 0, peer);
|
||||
g_signal_emit (peer, signals[SIGNAL_UNLINKED], 0, port);
|
||||
}
|
||||
port->priv->n_peers = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_port_get_n_links:
|
||||
* @port: a #PinosPort
|
||||
*
|
||||
* Get the number of links on this port
|
||||
*
|
||||
* Returns: the number of links
|
||||
*/
|
||||
gint
|
||||
pinos_port_get_n_links (PinosPort *port)
|
||||
{
|
||||
g_return_val_if_fail (PINOS_IS_PORT (port), -1);
|
||||
|
||||
return port->priv->n_peers;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_socket_condition (GSocket *socket,
|
||||
GIOCondition condition,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ struct _PinosStreamPrivate
|
|||
PinosDirection direction;
|
||||
gchar *path;
|
||||
GBytes *possible_formats;
|
||||
gboolean provide;
|
||||
PinosStreamFlags flags;
|
||||
|
||||
GBytes *format;
|
||||
|
||||
|
|
@ -553,6 +553,14 @@ on_node_created (GObject *source_object,
|
|||
if (priv->node == NULL)
|
||||
goto create_failed;
|
||||
|
||||
if (priv->properties == NULL)
|
||||
priv->properties = pinos_properties_new (NULL, NULL);
|
||||
|
||||
if (priv->flags & PINOS_STREAM_FLAG_AUTOCONNECT)
|
||||
pinos_properties_set (priv->properties, "autoconnect", "1");
|
||||
else
|
||||
pinos_properties_set (priv->properties, "autoconnect", "0");
|
||||
|
||||
pinos_node_create_port (priv->node,
|
||||
priv->direction,
|
||||
"client-port",
|
||||
|
|
@ -624,8 +632,8 @@ pinos_stream_connect (PinosStream *stream,
|
|||
priv->path = g_strdup (port_path);
|
||||
if (priv->possible_formats)
|
||||
g_bytes_unref (priv->possible_formats);
|
||||
priv->flags = flags;
|
||||
priv->possible_formats = possible_formats;
|
||||
priv->provide = FALSE;
|
||||
|
||||
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
|
||||
|
||||
|
|
@ -636,67 +644,6 @@ pinos_stream_connect (PinosStream *stream,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_connect_provide (PinosStream *stream)
|
||||
{
|
||||
#if 0
|
||||
PinosStreamPrivate *priv = stream->priv;
|
||||
PinosContext *context = priv->context;
|
||||
|
||||
g_dbus_proxy_call (context->priv->client,
|
||||
"CreateUploadChannel",
|
||||
g_variant_new ("(s@a{sv})",
|
||||
g_bytes_get_data (priv->possible_formats, NULL),
|
||||
pinos_properties_to_variant (priv->properties)),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL, /* GCancellable *cancellable */
|
||||
on_channel_created,
|
||||
stream);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_stream_connect_provide:
|
||||
* @stream: a #PinosStream
|
||||
* @flags: a #PinosStreamFlags
|
||||
* @possible_formats: (transfer full): a #GBytes
|
||||
*
|
||||
* Connect @stream for providing data for a new source.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
pinos_stream_connect_provide (PinosStream *stream,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats)
|
||||
{
|
||||
PinosStreamPrivate *priv;
|
||||
PinosContext *context;
|
||||
|
||||
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
|
||||
g_return_val_if_fail (possible_formats != NULL, FALSE);
|
||||
|
||||
priv = stream->priv;
|
||||
context = priv->context;
|
||||
g_return_val_if_fail (pinos_context_get_state (context) == PINOS_CONTEXT_STATE_CONNECTED, FALSE);
|
||||
|
||||
if (priv->possible_formats)
|
||||
g_bytes_unref (priv->possible_formats);
|
||||
priv->possible_formats = possible_formats;
|
||||
priv->provide = TRUE;
|
||||
|
||||
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
|
||||
|
||||
g_main_context_invoke (context->priv->context,
|
||||
(GSourceFunc) do_connect_provide,
|
||||
g_object_ref (stream));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_start (PinosStream *stream)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ typedef enum {
|
|||
const gchar * pinos_stream_state_as_string (PinosStreamState state);
|
||||
|
||||
typedef enum {
|
||||
PINOS_STREAM_FLAGS_NONE = 0,
|
||||
PINOS_STREAM_FLAG_NONE = 0,
|
||||
PINOS_STREAM_FLAG_AUTOCONNECT = (1 << 0),
|
||||
} PinosStreamFlags;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -96,9 +97,6 @@ gboolean pinos_stream_connect (PinosStream *stream,
|
|||
const gchar *port_path,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats);
|
||||
gboolean pinos_stream_connect_provide (PinosStream *stream,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats);
|
||||
gboolean pinos_stream_disconnect (PinosStream *stream);
|
||||
|
||||
gboolean pinos_stream_start (PinosStream *stream,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue