mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -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
				
			
		| 
						 | 
					@ -214,7 +214,6 @@ libpinoscore_@PINOS_MAJORMINOR@_la_SOURCES = \
 | 
				
			||||||
		server/daemon.c server/daemon.h \
 | 
							server/daemon.c server/daemon.h \
 | 
				
			||||||
		server/server-node.c server/server-node.h \
 | 
							server/server-node.c server/server-node.h \
 | 
				
			||||||
		server/server-port.c server/server-port.h \
 | 
							server/server-port.c server/server-port.h \
 | 
				
			||||||
		server/upload-node.c server/upload-node.h \
 | 
					 | 
				
			||||||
		modules/gst/gst-manager.c modules/gst/gst-manager.h \
 | 
							modules/gst/gst-manager.c modules/gst/gst-manager.h \
 | 
				
			||||||
		modules/gst/gst-source.c modules/gst/gst-source.h \
 | 
							modules/gst/gst-source.c modules/gst/gst-source.h \
 | 
				
			||||||
		modules/gst/gst-sink.c modules/gst/gst-sink.h \
 | 
							modules/gst/gst-sink.c modules/gst/gst-sink.h \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					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++) {
 | 
					  pinos_buffer_iter_init (&it, buffer);
 | 
				
			||||||
    PinosPort *peer = port->priv->peers[i];
 | 
					  while (pinos_buffer_iter_next (&it)) {
 | 
				
			||||||
    if (peer == NULL)
 | 
					    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;
 | 
					          continue;
 | 
				
			||||||
    if (peer->priv->peers[i] == port)
 | 
					
 | 
				
			||||||
      peer->priv->peers[i] = NULL;
 | 
					        if (priv->format)
 | 
				
			||||||
    port->priv->peers[i] = NULL;
 | 
					          g_bytes_unref (priv->format);
 | 
				
			||||||
    peer->priv->n_peers--;
 | 
					        priv->format = g_bytes_new (change.format, strlen (change.format) + 1);
 | 
				
			||||||
    g_signal_emit (port, signals[SIGNAL_UNLINKED], 0, peer);
 | 
					        g_object_notify (G_OBJECT (port), "format");
 | 
				
			||||||
    g_signal_emit (peer, signals[SIGNAL_UNLINKED], 0, port);
 | 
					        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 *
 | 
					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
 | 
					static gboolean
 | 
				
			||||||
pinos_port_receive_buffer (PinosPort   *port,
 | 
					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
 | 
					static gboolean
 | 
				
			||||||
on_socket_condition (GSocket      *socket,
 | 
					on_socket_condition (GSocket      *socket,
 | 
				
			||||||
                     GIOCondition  condition,
 | 
					                     GIOCondition  condition,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ struct _PinosStreamPrivate
 | 
				
			||||||
  PinosDirection direction;
 | 
					  PinosDirection direction;
 | 
				
			||||||
  gchar *path;
 | 
					  gchar *path;
 | 
				
			||||||
  GBytes *possible_formats;
 | 
					  GBytes *possible_formats;
 | 
				
			||||||
  gboolean provide;
 | 
					  PinosStreamFlags flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GBytes *format;
 | 
					  GBytes *format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,6 +553,14 @@ on_node_created (GObject      *source_object,
 | 
				
			||||||
  if (priv->node == NULL)
 | 
					  if (priv->node == NULL)
 | 
				
			||||||
    goto create_failed;
 | 
					    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,
 | 
					  pinos_node_create_port (priv->node,
 | 
				
			||||||
                          priv->direction,
 | 
					                          priv->direction,
 | 
				
			||||||
                          "client-port",
 | 
					                          "client-port",
 | 
				
			||||||
| 
						 | 
					@ -624,8 +632,8 @@ pinos_stream_connect (PinosStream      *stream,
 | 
				
			||||||
  priv->path = g_strdup (port_path);
 | 
					  priv->path = g_strdup (port_path);
 | 
				
			||||||
  if (priv->possible_formats)
 | 
					  if (priv->possible_formats)
 | 
				
			||||||
    g_bytes_unref (priv->possible_formats);
 | 
					    g_bytes_unref (priv->possible_formats);
 | 
				
			||||||
 | 
					  priv->flags = flags;
 | 
				
			||||||
  priv->possible_formats = possible_formats;
 | 
					  priv->possible_formats = possible_formats;
 | 
				
			||||||
  priv->provide = FALSE;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
 | 
					  stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -636,67 +644,6 @@ pinos_stream_connect (PinosStream      *stream,
 | 
				
			||||||
  return TRUE;
 | 
					  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
 | 
					static gboolean
 | 
				
			||||||
do_start (PinosStream *stream)
 | 
					do_start (PinosStream *stream)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,8 @@ typedef enum {
 | 
				
			||||||
const gchar * pinos_stream_state_as_string (PinosStreamState state);
 | 
					const gchar * pinos_stream_state_as_string (PinosStreamState state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
  PINOS_STREAM_FLAGS_NONE = 0,
 | 
					  PINOS_STREAM_FLAG_NONE = 0,
 | 
				
			||||||
 | 
					  PINOS_STREAM_FLAG_AUTOCONNECT = (1 << 0),
 | 
				
			||||||
} PinosStreamFlags;
 | 
					} PinosStreamFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
| 
						 | 
					@ -96,9 +97,6 @@ gboolean         pinos_stream_connect           (PinosStream      *stream,
 | 
				
			||||||
                                                 const gchar      *port_path,
 | 
					                                                 const gchar      *port_path,
 | 
				
			||||||
                                                 PinosStreamFlags  flags,
 | 
					                                                 PinosStreamFlags  flags,
 | 
				
			||||||
                                                 GBytes           *possible_formats);
 | 
					                                                 GBytes           *possible_formats);
 | 
				
			||||||
gboolean         pinos_stream_connect_provide   (PinosStream      *stream,
 | 
					 | 
				
			||||||
                                                 PinosStreamFlags  flags,
 | 
					 | 
				
			||||||
                                                 GBytes           *possible_formats);
 | 
					 | 
				
			||||||
gboolean         pinos_stream_disconnect        (PinosStream      *stream);
 | 
					gboolean         pinos_stream_disconnect        (PinosStream      *stream);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
gboolean         pinos_stream_start             (PinosStream     *stream,
 | 
					gboolean         pinos_stream_start             (PinosStream     *stream,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -76,6 +76,16 @@
 | 
				
			||||||
      <arg type='h' name='fd' direction='out'/>
 | 
					      <arg type='h' name='fd' direction='out'/>
 | 
				
			||||||
    </method>
 | 
					    </method>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- Activate:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         Set the node ready for processing
 | 
				
			||||||
 | 
					    -->
 | 
				
			||||||
 | 
					    <method name='Activate'>
 | 
				
			||||||
 | 
					    </method>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <method name='Deactivate'>
 | 
				
			||||||
 | 
					    </method>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- Remove:
 | 
					    <!-- Remove:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         Remove the node
 | 
					         Remove the node
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -425,17 +425,16 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 | 
				
			||||||
    goto start_error;
 | 
					    goto start_error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (state == PINOS_STREAM_STATE_UNCONNECTED) {
 | 
					  if (state == PINOS_STREAM_STATE_UNCONNECTED) {
 | 
				
			||||||
    if (pinossink->mode == GST_PINOS_SINK_MODE_PROVIDE) {
 | 
					    PinosStreamFlags flags = 0;
 | 
				
			||||||
      pinos_stream_connect_provide (pinossink->stream,
 | 
					
 | 
				
			||||||
                            0,
 | 
					    if (pinossink->mode != GST_PINOS_SINK_MODE_PROVIDE)
 | 
				
			||||||
                            g_bytes_ref (format));
 | 
					      flags |= PINOS_STREAM_FLAG_AUTOCONNECT;
 | 
				
			||||||
    } else {
 | 
					
 | 
				
			||||||
    pinos_stream_connect (pinossink->stream,
 | 
					    pinos_stream_connect (pinossink->stream,
 | 
				
			||||||
                          PINOS_DIRECTION_OUTPUT,
 | 
					                          PINOS_DIRECTION_OUTPUT,
 | 
				
			||||||
                          pinossink->path,
 | 
					                          pinossink->path,
 | 
				
			||||||
                            0,
 | 
					                          flags,
 | 
				
			||||||
                          g_bytes_ref (format));
 | 
					                          g_bytes_ref (format));
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (TRUE) {
 | 
					    while (TRUE) {
 | 
				
			||||||
      state = pinos_stream_get_state (pinossink->stream);
 | 
					      state = pinos_stream_get_state (pinossink->stream);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -653,7 +653,11 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path);
 | 
					    GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path);
 | 
				
			||||||
    pinos_stream_connect (pinossrc->stream, PINOS_DIRECTION_INPUT, pinossrc->path, 0, accepted);
 | 
					    pinos_stream_connect (pinossrc->stream,
 | 
				
			||||||
 | 
					                          PINOS_DIRECTION_INPUT,
 | 
				
			||||||
 | 
					                          pinossrc->path,
 | 
				
			||||||
 | 
					                          PINOS_STREAM_FLAG_AUTOCONNECT,
 | 
				
			||||||
 | 
					                          accepted);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (TRUE) {
 | 
					    while (TRUE) {
 | 
				
			||||||
      PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
 | 
					      PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,6 +161,7 @@ handle_create_node (PinosDaemon1           *interface,
 | 
				
			||||||
  g_debug ("daemon %p: create node: %s", daemon, sender);
 | 
					  g_debug ("daemon %p: create node: %s", daemon, sender);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  props = pinos_properties_from_variant (arg_properties);
 | 
					  props = pinos_properties_from_variant (arg_properties);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  node = pinos_server_node_new (daemon,
 | 
					  node = pinos_server_node_new (daemon,
 | 
				
			||||||
                                sender,
 | 
					                                sender,
 | 
				
			||||||
                                arg_name,
 | 
					                                arg_name,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gio/gio.h>
 | 
					#include <gio/gio.h>
 | 
				
			||||||
#include <gio/gunixfdlist.h>
 | 
					#include <gio/gunixfdlist.h>
 | 
				
			||||||
| 
						 | 
					@ -99,12 +100,14 @@ on_port_created (GObject      *source_object,
 | 
				
			||||||
  PinosServerNodePrivate *priv = PINOS_SERVER_NODE (node)->priv;
 | 
					  PinosServerNodePrivate *priv = PINOS_SERVER_NODE (node)->priv;
 | 
				
			||||||
  GDBusMethodInvocation *invocation = user_data;
 | 
					  GDBusMethodInvocation *invocation = user_data;
 | 
				
			||||||
  PinosPort *port, *peer;
 | 
					  PinosPort *port, *peer;
 | 
				
			||||||
  const gchar *object_path;
 | 
					  const gchar *object_path, *val;
 | 
				
			||||||
  GError *error = NULL;
 | 
					  GError *error = NULL;
 | 
				
			||||||
  GUnixFDList *fdlist;
 | 
					  GUnixFDList *fdlist;
 | 
				
			||||||
  GSocket *socket;
 | 
					  GSocket *socket;
 | 
				
			||||||
  int fd, fdidx;
 | 
					  int fd, fdidx;
 | 
				
			||||||
  PinosDirection direction;
 | 
					  PinosDirection direction;
 | 
				
			||||||
 | 
					  PinosProperties *props;
 | 
				
			||||||
 | 
					  gboolean autoconnect = FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  port = pinos_node_create_port_finish (node, res, &error);
 | 
					  port = pinos_node_create_port_finish (node, res, &error);
 | 
				
			||||||
  if (port == NULL)
 | 
					  if (port == NULL)
 | 
				
			||||||
| 
						 | 
					@ -124,6 +127,14 @@ on_port_created (GObject      *source_object,
 | 
				
			||||||
  if (fdidx == -1)
 | 
					  if (fdidx == -1)
 | 
				
			||||||
    goto no_fdlist;
 | 
					    goto no_fdlist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  props = pinos_port_get_properties (port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ((val = pinos_properties_get (props, "autoconnect"))) {
 | 
				
			||||||
 | 
					    autoconnect = atoi (val);
 | 
				
			||||||
 | 
					  } else
 | 
				
			||||||
 | 
					    autoconnect = TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (autoconnect) {
 | 
				
			||||||
    direction = pinos_port_get_direction (port);
 | 
					    direction = pinos_port_get_direction (port);
 | 
				
			||||||
    direction = pinos_direction_reverse (direction);
 | 
					    direction = pinos_direction_reverse (direction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,6 +148,7 @@ on_port_created (GObject      *source_object,
 | 
				
			||||||
      goto no_port_found;
 | 
					      goto no_port_found;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pinos_port_link (port, peer);
 | 
					    pinos_port_link (port, peer);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  object_path = pinos_server_port_get_object_path (PINOS_SERVER_PORT (port));
 | 
					  object_path = pinos_server_port_get_object_path (PINOS_SERVER_PORT (port));
 | 
				
			||||||
  g_debug ("server-node %p: add port %p, remote fd %d, %s", node, port, fd, object_path);
 | 
					  g_debug ("server-node %p: add port %p, remote fd %d, %s", node, port, fd, object_path);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,324 +0,0 @@
 | 
				
			||||||
/* Pinos
 | 
					 | 
				
			||||||
 * Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Library General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Library General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Library General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the
 | 
					 | 
				
			||||||
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
					 | 
				
			||||||
 * Boston, MA 02110-1301, USA.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <gst/gst.h>
 | 
					 | 
				
			||||||
#include <gio/gio.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <pinos/server/daemon.h>
 | 
					 | 
				
			||||||
#include <pinos/server/upload-node.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE_GET_PRIVATE(obj)  \
 | 
					 | 
				
			||||||
     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_UPLOAD_NODE, PinosUploadNodePrivate))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct _PinosUploadNodePrivate
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  GstElement *pipeline;
 | 
					 | 
				
			||||||
  GstElement *src;
 | 
					 | 
				
			||||||
  GstElement *sink;
 | 
					 | 
				
			||||||
  guint id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  GstCaps *format;
 | 
					 | 
				
			||||||
  GBytes *possible_formats;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  PinosPort *input, *output;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
G_DEFINE_TYPE (PinosUploadNode, pinos_upload_node, PINOS_TYPE_SERVER_NODE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PROP_0,
 | 
					 | 
				
			||||||
  PROP_POSSIBLE_FORMATS
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
upload_node_get_property (GObject    *_object,
 | 
					 | 
				
			||||||
                            guint       prop_id,
 | 
					 | 
				
			||||||
                            GValue     *value,
 | 
					 | 
				
			||||||
                            GParamSpec *pspec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNode *node = PINOS_UPLOAD_NODE (_object);
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = node->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (prop_id) {
 | 
					 | 
				
			||||||
    case PROP_POSSIBLE_FORMATS:
 | 
					 | 
				
			||||||
      g_value_set_boxed (value, priv->possible_formats);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (node, prop_id, pspec);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
upload_node_set_property (GObject      *_object,
 | 
					 | 
				
			||||||
                            guint         prop_id,
 | 
					 | 
				
			||||||
                            const GValue *value,
 | 
					 | 
				
			||||||
                            GParamSpec   *pspec)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNode *node = PINOS_UPLOAD_NODE (_object);
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = node->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (prop_id) {
 | 
					 | 
				
			||||||
    case PROP_POSSIBLE_FORMATS:
 | 
					 | 
				
			||||||
      if (priv->possible_formats)
 | 
					 | 
				
			||||||
        g_bytes_unref (priv->possible_formats);
 | 
					 | 
				
			||||||
      priv->possible_formats = g_value_dup_boxed (value);
 | 
					 | 
				
			||||||
      if (priv->output)
 | 
					 | 
				
			||||||
        g_object_set (priv->output, "possible-formats", priv->possible_formats, NULL);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (node, prop_id, pspec);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static gboolean
 | 
					 | 
				
			||||||
bus_handler (GstBus     *bus,
 | 
					 | 
				
			||||||
             GstMessage *message,
 | 
					 | 
				
			||||||
             gpointer    user_data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosServerNode *node = user_data;
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (node)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (GST_MESSAGE_TYPE (message)) {
 | 
					 | 
				
			||||||
    case GST_MESSAGE_ERROR:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      GError *error;
 | 
					 | 
				
			||||||
      gchar *debug;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      gst_message_parse_error (message, &error, &debug);
 | 
					 | 
				
			||||||
      g_warning ("got error %s (%s)\n", error->message, debug);
 | 
					 | 
				
			||||||
      g_free (debug);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      pinos_node_report_error (PINOS_NODE (node), error);
 | 
					 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_NULL);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    case GST_MESSAGE_ELEMENT:
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      if (gst_message_has_name (message, "PinosPayloaderFormatChange")) {
 | 
					 | 
				
			||||||
        const GstStructure *str = gst_message_get_structure (message);
 | 
					 | 
				
			||||||
        GstCaps *caps;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        gst_structure_get (str, "format", GST_TYPE_CAPS, &caps, NULL);
 | 
					 | 
				
			||||||
        gst_caps_replace (&priv->format, caps);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return TRUE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
setup_pipeline (PinosUploadNode *node)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = node->priv;
 | 
					 | 
				
			||||||
  GstBus *bus;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_debug ("upload-node %p: setup pipeline", node);
 | 
					 | 
				
			||||||
  priv->pipeline = gst_parse_launch ("socketsrc "
 | 
					 | 
				
			||||||
                                         "name=src "
 | 
					 | 
				
			||||||
                                         "caps=application/x-pinos "
 | 
					 | 
				
			||||||
                                         "send-messages=true ! "
 | 
					 | 
				
			||||||
                                     "pinossocketsink "
 | 
					 | 
				
			||||||
                                         "name=sink "
 | 
					 | 
				
			||||||
                                         "enable-last-sample=false ",
 | 
					 | 
				
			||||||
                                      NULL);
 | 
					 | 
				
			||||||
  priv->sink = gst_bin_get_by_name (GST_BIN (priv->pipeline), "sink");
 | 
					 | 
				
			||||||
  priv->src = gst_bin_get_by_name (GST_BIN (priv->pipeline), "src");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
 | 
					 | 
				
			||||||
  priv->id = gst_bus_add_watch (bus, bus_handler, node);
 | 
					 | 
				
			||||||
  gst_object_unref (bus);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static gboolean
 | 
					 | 
				
			||||||
node_set_state (PinosNode       *node,
 | 
					 | 
				
			||||||
                PinosNodeState   state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (node)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (state) {
 | 
					 | 
				
			||||||
    case PINOS_NODE_STATE_SUSPENDED:
 | 
					 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_NULL);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_NODE_STATE_INITIALIZING:
 | 
					 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_READY);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_NODE_STATE_IDLE:
 | 
					 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_NODE_STATE_RUNNING:
 | 
					 | 
				
			||||||
      gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case PINOS_NODE_STATE_ERROR:
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  pinos_node_update_state (node, state);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return TRUE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
upload_node_dispose (GObject * object)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (object)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_debug ("upload-node %p: dispose", object);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_source_remove (priv->id);
 | 
					 | 
				
			||||||
  gst_element_set_state (priv->pipeline, GST_STATE_NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  G_OBJECT_CLASS (pinos_upload_node_parent_class)->dispose (object);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
upload_node_finalize (GObject * object)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (object)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_debug ("upload-node %p: finalize", object);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_clear_object (&priv->sink);
 | 
					 | 
				
			||||||
  g_clear_object (&priv->src);
 | 
					 | 
				
			||||||
  g_clear_object (&priv->pipeline);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (priv->possible_formats)
 | 
					 | 
				
			||||||
    g_bytes_unref (priv->possible_formats);
 | 
					 | 
				
			||||||
  gst_caps_replace (&priv->format, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  G_OBJECT_CLASS (pinos_upload_node_parent_class)->finalize (object);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
on_input_port_created (GObject      *source_object,
 | 
					 | 
				
			||||||
                       GAsyncResult *res,
 | 
					 | 
				
			||||||
                       gpointer      user_data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosNode *node = PINOS_NODE (source_object);
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (source_object)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  priv->input = pinos_node_create_port_finish (node, res, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
on_output_port_created (GObject      *source_object,
 | 
					 | 
				
			||||||
                        GAsyncResult *res,
 | 
					 | 
				
			||||||
                        gpointer      user_data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosNode *node = PINOS_NODE (source_object);
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = PINOS_UPLOAD_NODE (source_object)->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  priv->output = pinos_node_create_port_finish (node, res, NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
upload_node_constructed (GObject * object)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PinosServerNode *node = PINOS_SERVER_NODE (object);
 | 
					 | 
				
			||||||
  PinosUploadNode *upload = PINOS_UPLOAD_NODE (object);
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv = upload->priv;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  G_OBJECT_CLASS (pinos_upload_node_parent_class)->constructed (object);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_debug ("upload-node %p: constructed", upload);
 | 
					 | 
				
			||||||
  pinos_node_create_port (PINOS_NODE (node),
 | 
					 | 
				
			||||||
                                PINOS_DIRECTION_INPUT,
 | 
					 | 
				
			||||||
                                "input",
 | 
					 | 
				
			||||||
                                 priv->possible_formats,
 | 
					 | 
				
			||||||
                                NULL,
 | 
					 | 
				
			||||||
                                NULL,
 | 
					 | 
				
			||||||
                                on_input_port_created,
 | 
					 | 
				
			||||||
                                node);
 | 
					 | 
				
			||||||
  pinos_node_create_port (PINOS_NODE (node),
 | 
					 | 
				
			||||||
                                 PINOS_DIRECTION_OUTPUT,
 | 
					 | 
				
			||||||
                                 "output",
 | 
					 | 
				
			||||||
                                 priv->possible_formats,
 | 
					 | 
				
			||||||
                                 NULL,
 | 
					 | 
				
			||||||
                                 NULL,
 | 
					 | 
				
			||||||
                                 on_output_port_created,
 | 
					 | 
				
			||||||
                                 node);
 | 
					 | 
				
			||||||
  setup_pipeline (upload);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
pinos_upload_node_class_init (PinosUploadNodeClass * klass)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
					 | 
				
			||||||
  PinosNodeClass *node_class = PINOS_NODE_CLASS (klass);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_type_class_add_private (klass, sizeof (PinosUploadNodePrivate));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  gobject_class->constructed = upload_node_constructed;
 | 
					 | 
				
			||||||
  gobject_class->dispose = upload_node_dispose;
 | 
					 | 
				
			||||||
  gobject_class->finalize = upload_node_finalize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  gobject_class->get_property = upload_node_get_property;
 | 
					 | 
				
			||||||
  gobject_class->set_property = upload_node_set_property;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  g_object_class_install_property (gobject_class,
 | 
					 | 
				
			||||||
                                   PROP_POSSIBLE_FORMATS,
 | 
					 | 
				
			||||||
                                   g_param_spec_boxed ("possible-formats",
 | 
					 | 
				
			||||||
                                                       "Possible Format",
 | 
					 | 
				
			||||||
                                                       "The possible formats of the stream",
 | 
					 | 
				
			||||||
                                                       G_TYPE_BYTES,
 | 
					 | 
				
			||||||
                                                       G_PARAM_READWRITE |
 | 
					 | 
				
			||||||
                                                       G_PARAM_CONSTRUCT |
 | 
					 | 
				
			||||||
                                                       G_PARAM_STATIC_STRINGS));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  node_class->set_state = node_set_state;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
pinos_upload_node_init (PinosUploadNode * node)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  node->priv = PINOS_UPLOAD_NODE_GET_PRIVATE (node);
 | 
					 | 
				
			||||||
  g_debug ("upload-node %p: new", node);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * pinos_upload_node_new:
 | 
					 | 
				
			||||||
 * @daemon: the parent #PinosDaemon
 | 
					 | 
				
			||||||
 * @possible_formats: a #GBytes
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Make a new #PinosServerNode that can be used to receive data from a client.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Returns: a new #PinosServerNode.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
PinosServerNode *
 | 
					 | 
				
			||||||
pinos_upload_node_new (PinosDaemon *daemon,
 | 
					 | 
				
			||||||
                       GBytes      *possible_formats)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return g_object_new (PINOS_TYPE_UPLOAD_NODE,
 | 
					 | 
				
			||||||
                       "daemon", daemon,
 | 
					 | 
				
			||||||
                       "name", "upload-node",
 | 
					 | 
				
			||||||
                       "possible-formats", possible_formats,
 | 
					 | 
				
			||||||
                       NULL);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,70 +0,0 @@
 | 
				
			||||||
/* Pinos
 | 
					 | 
				
			||||||
 * Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is free software; you can redistribute it and/or
 | 
					 | 
				
			||||||
 * modify it under the terms of the GNU Library General Public
 | 
					 | 
				
			||||||
 * License as published by the Free Software Foundation; either
 | 
					 | 
				
			||||||
 * version 2 of the License, or (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
					 | 
				
			||||||
 * Library General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU Library General Public
 | 
					 | 
				
			||||||
 * License along with this library; if not, write to the
 | 
					 | 
				
			||||||
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 | 
					 | 
				
			||||||
 * Boston, MA 02110-1301, USA.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __PINOS_UPLOAD_NODE_H__
 | 
					 | 
				
			||||||
#define __PINOS_UPLOAD_NODE_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <glib-object.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
G_BEGIN_DECLS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct _PinosUploadNode PinosUploadNode;
 | 
					 | 
				
			||||||
typedef struct _PinosUploadNodeClass PinosUploadNodeClass;
 | 
					 | 
				
			||||||
typedef struct _PinosUploadNodePrivate PinosUploadNodePrivate;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <pinos/server/server-node.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define PINOS_TYPE_UPLOAD_NODE                 (pinos_upload_node_get_type ())
 | 
					 | 
				
			||||||
#define PINOS_IS_UPLOAD_NODE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_UPLOAD_NODE))
 | 
					 | 
				
			||||||
#define PINOS_IS_UPLOAD_NODE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_UPLOAD_NODE))
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_UPLOAD_NODE, PinosUploadNodeClass))
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_UPLOAD_NODE, PinosUploadNode))
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_UPLOAD_NODE, PinosUploadNodeClass))
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE_CAST(obj)            ((PinosUploadNode*)(obj))
 | 
					 | 
				
			||||||
#define PINOS_UPLOAD_NODE_CLASS_CAST(klass)    ((PinosUploadNodeClass*)(klass))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * PinosUploadNode:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Pinos client source object class.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct _PinosUploadNode {
 | 
					 | 
				
			||||||
  PinosServerNode object;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  PinosUploadNodePrivate *priv;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * PinosUploadNodeClass:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Pinos client source object class.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
struct _PinosUploadNodeClass {
 | 
					 | 
				
			||||||
  PinosServerNodeClass parent_class;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* normal GObject stuff */
 | 
					 | 
				
			||||||
GType               pinos_upload_node_get_type         (void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PinosServerNode *   pinos_upload_node_new              (PinosDaemon *daemon,
 | 
					 | 
				
			||||||
                                                        GBytes      *possible_formats);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
G_END_DECLS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* __PINOS_UPLOAD_NODE_H__ */
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue