mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-26 07:00:13 -05:00
Introduce the concept of a Port
A port is an input or output on a Node. Channels are created from the ports and inherit the direction of the port. do automatic port selection based on the direction and caps and node/port name. Simplify stream_connect by passing the direction. Fix pinossink to connect in setcaps so that we know the format and can select a good sink to connect to.
This commit is contained in:
parent
b885d40390
commit
ba4ef9b5d9
35 changed files with 1939 additions and 2120 deletions
|
|
@ -191,19 +191,21 @@ enum
|
|||
};
|
||||
|
||||
static GstDevice *
|
||||
new_source (const PinosSourceInfo *info)
|
||||
new_node (const PinosNodeInfo *info)
|
||||
{
|
||||
GstCaps *caps;
|
||||
GstStructure *props;
|
||||
gpointer state = NULL;
|
||||
const gchar *klass;
|
||||
|
||||
/* FIXME, iterate ports */
|
||||
#if 0
|
||||
if (info->possible_formats)
|
||||
caps = gst_caps_from_string (g_bytes_get_data (info->possible_formats, NULL));
|
||||
else
|
||||
#endif
|
||||
caps = gst_caps_new_any();
|
||||
|
||||
|
||||
props = gst_structure_new_empty ("pinos-proplist");
|
||||
|
||||
while (TRUE) {
|
||||
|
|
@ -223,21 +225,21 @@ new_source (const PinosSourceInfo *info)
|
|||
return gst_pinos_device_new (info->id,
|
||||
info->name,
|
||||
caps,
|
||||
info->source_path,
|
||||
info->node_path,
|
||||
klass,
|
||||
GST_PINOS_DEVICE_TYPE_SOURCE,
|
||||
props);
|
||||
}
|
||||
|
||||
static void
|
||||
get_source_info_cb (PinosContext *context,
|
||||
const PinosSourceInfo *info,
|
||||
gpointer user_data)
|
||||
get_node_info_cb (PinosContext *context,
|
||||
const PinosNodeInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
GstPinosDeviceProvider *self = user_data;
|
||||
GstDevice *dev;
|
||||
|
||||
dev = new_source (info);
|
||||
dev = new_node (info);
|
||||
if (dev)
|
||||
gst_device_provider_device_add (GST_DEVICE_PROVIDER (self), dev);
|
||||
}
|
||||
|
|
@ -273,22 +275,22 @@ context_subscribe_cb (PinosContext *context,
|
|||
GstDeviceProvider *provider = user_data;
|
||||
GstPinosDevice *dev;
|
||||
|
||||
if (flags != PINOS_SUBSCRIPTION_FLAG_SOURCE)
|
||||
if (flags != PINOS_SUBSCRIPTION_FLAG_NODE)
|
||||
return;
|
||||
|
||||
dev = find_device (provider, id);
|
||||
|
||||
if (type == PINOS_SUBSCRIPTION_EVENT_NEW) {
|
||||
if (flags == PINOS_SUBSCRIPTION_FLAG_SOURCE && dev == NULL)
|
||||
pinos_context_get_source_info_by_id (context,
|
||||
id,
|
||||
PINOS_SOURCE_INFO_FLAGS_FORMATS,
|
||||
get_source_info_cb,
|
||||
NULL,
|
||||
NULL,
|
||||
self);
|
||||
if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev == NULL)
|
||||
pinos_context_get_node_info_by_id (context,
|
||||
id,
|
||||
PINOS_NODE_INFO_FLAGS_NONE,
|
||||
get_node_info_cb,
|
||||
NULL,
|
||||
NULL,
|
||||
self);
|
||||
} else if (type == PINOS_SUBSCRIPTION_EVENT_REMOVE) {
|
||||
if (flags == PINOS_SUBSCRIPTION_FLAG_SOURCE && dev != NULL) {
|
||||
if (flags == PINOS_SUBSCRIPTION_FLAG_NODE && dev != NULL) {
|
||||
gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self),
|
||||
GST_DEVICE (dev));
|
||||
}
|
||||
|
|
@ -303,25 +305,25 @@ typedef struct {
|
|||
} InfoData;
|
||||
|
||||
static void
|
||||
list_source_info_cb (PinosContext *c,
|
||||
const PinosSourceInfo *info,
|
||||
gpointer user_data)
|
||||
list_node_info_cb (PinosContext *c,
|
||||
const PinosNodeInfo *info,
|
||||
gpointer user_data)
|
||||
{
|
||||
InfoData *data = user_data;
|
||||
|
||||
*data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (new_source (info)));
|
||||
*data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (new_node (info)));
|
||||
}
|
||||
|
||||
static void
|
||||
list_source_info_end_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
list_node_info_end_cb (GObject *source_object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
InfoData *data = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!pinos_context_info_finish (source_object, res, &error)) {
|
||||
GST_WARNING_OBJECT (source_object, "failed to list sources: %s", error->message);
|
||||
GST_WARNING_OBJECT (source_object, "failed to list nodes: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
data->end = TRUE;
|
||||
|
|
@ -396,12 +398,12 @@ gst_pinos_device_provider_probe (GstDeviceProvider * provider)
|
|||
|
||||
data.end = FALSE;
|
||||
data.devices = NULL;
|
||||
pinos_context_list_source_info (c,
|
||||
PINOS_SOURCE_INFO_FLAGS_FORMATS,
|
||||
list_source_info_cb,
|
||||
NULL,
|
||||
list_source_info_end_cb,
|
||||
&data);
|
||||
pinos_context_list_node_info (c,
|
||||
PINOS_NODE_INFO_FLAGS_NONE,
|
||||
list_node_info_cb,
|
||||
NULL,
|
||||
list_node_info_end_cb,
|
||||
&data);
|
||||
for (;;) {
|
||||
if (pinos_context_get_state (c) <= 0)
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -366,12 +366,14 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
{
|
||||
GstPinosSink *pinossink;
|
||||
gchar *str;
|
||||
GBytes *format;
|
||||
PinosStreamState state;
|
||||
gboolean res = FALSE;
|
||||
|
||||
pinossink = GST_PINOS_SINK (bsink);
|
||||
|
||||
str = gst_caps_to_string (caps);
|
||||
format = g_bytes_new_take (str, strlen (str) + 1);
|
||||
|
||||
pinos_main_loop_lock (pinossink->loop);
|
||||
state = pinos_stream_get_state (pinossink->stream);
|
||||
|
|
@ -379,6 +381,26 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
if (state == PINOS_STREAM_STATE_ERROR)
|
||||
goto start_error;
|
||||
|
||||
if (state == PINOS_STREAM_STATE_UNCONNECTED) {
|
||||
pinos_stream_connect (pinossink->stream,
|
||||
PINOS_DIRECTION_INPUT,
|
||||
pinossink->path,
|
||||
0,
|
||||
g_bytes_ref (format));
|
||||
|
||||
while (TRUE) {
|
||||
state = pinos_stream_get_state (pinossink->stream);
|
||||
|
||||
if (state == PINOS_STREAM_STATE_READY)
|
||||
break;
|
||||
|
||||
if (state == PINOS_STREAM_STATE_ERROR)
|
||||
goto start_error;
|
||||
|
||||
pinos_main_loop_wait (pinossink->loop);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == PINOS_STREAM_STATE_STREAMING) {
|
||||
PinosBufferBuilder builder;
|
||||
PinosPacketFormatChange change;
|
||||
|
|
@ -387,16 +409,16 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
pinos_buffer_builder_init (&builder);
|
||||
|
||||
change.id = 1;
|
||||
change.format = str;
|
||||
change.format = g_bytes_get_data (format, NULL);
|
||||
pinos_buffer_builder_add_format_change (&builder, &change);
|
||||
pinos_buffer_builder_end (&builder, &pbuf);
|
||||
|
||||
res = pinos_stream_send_buffer (pinossink->stream, &pbuf);
|
||||
pinos_buffer_clear (&pbuf);
|
||||
} else {
|
||||
GBytes *format = g_bytes_new_take (str, strlen (str) + 1);
|
||||
|
||||
res = pinos_stream_start (pinossink->stream, format, PINOS_STREAM_MODE_BUFFER);
|
||||
res = pinos_stream_start (pinossink->stream,
|
||||
g_bytes_ref (format),
|
||||
PINOS_STREAM_MODE_BUFFER);
|
||||
|
||||
while (TRUE) {
|
||||
state = pinos_stream_get_state (pinossink->stream);
|
||||
|
|
@ -411,6 +433,7 @@ gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
}
|
||||
}
|
||||
pinos_main_loop_unlock (pinossink->loop);
|
||||
g_bytes_unref (format);
|
||||
|
||||
pinossink->negotiated = res;
|
||||
|
||||
|
|
@ -420,6 +443,7 @@ start_error:
|
|||
{
|
||||
GST_ERROR ("could not start stream");
|
||||
pinos_main_loop_unlock (pinossink->loop);
|
||||
g_bytes_unref (format);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -563,32 +587,9 @@ gst_pinos_sink_start (GstBaseSink * basesink)
|
|||
pinossink->stream = pinos_stream_new (pinossink->ctx, pinossink->client_name, props);
|
||||
g_signal_connect (pinossink->stream, "notify::state", (GCallback) on_stream_notify, pinossink);
|
||||
g_signal_connect (pinossink->stream, "new-buffer", (GCallback) on_new_buffer, pinossink);
|
||||
|
||||
pinos_stream_connect_sink (pinossink->stream, pinossink->path, 0, g_bytes_new_static ("ANY", strlen ("ANY")+1));
|
||||
|
||||
while (TRUE) {
|
||||
PinosStreamState state = pinos_stream_get_state (pinossink->stream);
|
||||
|
||||
if (state == PINOS_STREAM_STATE_READY)
|
||||
break;
|
||||
|
||||
if (state == PINOS_STREAM_STATE_ERROR)
|
||||
goto connect_error;
|
||||
|
||||
pinos_main_loop_wait (pinossink->loop);
|
||||
}
|
||||
pinos_main_loop_unlock (pinossink->loop);
|
||||
|
||||
pinossink->negotiated = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
||||
connect_error:
|
||||
{
|
||||
GST_ERROR ("could not connect stream");
|
||||
pinos_main_loop_unlock (pinossink->loop);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ gst_pinos_src_negotiate (GstBaseSrc * basesrc)
|
|||
}
|
||||
|
||||
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pinossrc->path);
|
||||
pinos_stream_connect_source (pinossrc->stream, pinossrc->path, 0, accepted);
|
||||
pinos_stream_connect (pinossrc->stream, PINOS_DIRECTION_OUTPUT, pinossrc->path, 0, accepted);
|
||||
|
||||
while (TRUE) {
|
||||
PinosStreamState state = pinos_stream_get_state (pinossrc->stream);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue