mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-21 07:00:08 -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
|
|
@ -189,7 +189,7 @@ gboolean pinos_buffer_builder_add_release_fd_payload (PinosBufferBuil
|
|||
*/
|
||||
typedef struct {
|
||||
guint8 id;
|
||||
gchar *format;
|
||||
const gchar *format;
|
||||
} PinosPacketFormatChange;
|
||||
|
||||
gboolean pinos_buffer_iter_parse_format_change (PinosBufferIter *iter,
|
||||
|
|
@ -207,8 +207,8 @@ gboolean pinos_buffer_builder_add_format_change (PinosBufferBuilder
|
|||
* A new property change.
|
||||
*/
|
||||
typedef struct {
|
||||
gchar *key;
|
||||
gchar *value;
|
||||
const gchar *key;
|
||||
const gchar *value;
|
||||
} PinosPacketPropertyChange;
|
||||
|
||||
gboolean pinos_buffer_iter_parse_property_change (PinosBufferIter *iter,
|
||||
|
|
|
|||
|
|
@ -147,8 +147,8 @@ pinos_context_finalize (GObject * object)
|
|||
if (priv->properties)
|
||||
pinos_properties_free (priv->properties);
|
||||
|
||||
g_list_free (priv->sources);
|
||||
g_list_free (priv->sinks);
|
||||
g_list_free (priv->nodes);
|
||||
g_list_free (priv->ports);
|
||||
g_list_free (priv->clients);
|
||||
g_list_free (priv->channels);
|
||||
g_clear_object (&priv->subscribe);
|
||||
|
|
@ -488,18 +488,18 @@ subscription_cb (PinosSubscribe *subscribe,
|
|||
}
|
||||
break;
|
||||
|
||||
case PINOS_SUBSCRIPTION_FLAG_SOURCE:
|
||||
case PINOS_SUBSCRIPTION_FLAG_NODE:
|
||||
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
|
||||
priv->sources = g_list_prepend (priv->sources, object);
|
||||
priv->nodes = g_list_prepend (priv->nodes, object);
|
||||
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
|
||||
priv->sources = g_list_remove (priv->sources, object);
|
||||
priv->nodes = g_list_remove (priv->nodes, object);
|
||||
break;
|
||||
|
||||
case PINOS_SUBSCRIPTION_FLAG_SINK:
|
||||
case PINOS_SUBSCRIPTION_FLAG_PORT:
|
||||
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
|
||||
priv->sinks = g_list_prepend (priv->sinks, object);
|
||||
priv->ports = g_list_prepend (priv->ports, object);
|
||||
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
|
||||
priv->sinks = g_list_remove (priv->sinks, object);
|
||||
priv->ports = g_list_remove (priv->ports, object);
|
||||
break;
|
||||
|
||||
case PINOS_SUBSCRIPTION_FLAG_CHANNEL:
|
||||
|
|
|
|||
|
|
@ -274,69 +274,66 @@ pinos_context_get_client_info_by_id (PinosContext *context,
|
|||
}
|
||||
|
||||
/**
|
||||
* pinos_source_state_as_string:
|
||||
* @state: a #PinosSourceState
|
||||
* pinos_node_state_as_string:
|
||||
* @state: a #PinosNodeeState
|
||||
*
|
||||
* Return the string representation of @state.
|
||||
*
|
||||
* Returns: the string representation of @state.
|
||||
*/
|
||||
const gchar *
|
||||
pinos_source_state_as_string (PinosSourceState state)
|
||||
pinos_node_state_as_string (PinosNodeState state)
|
||||
{
|
||||
GEnumValue *val;
|
||||
|
||||
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_SOURCE_STATE)),
|
||||
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_NODE_STATE)),
|
||||
state);
|
||||
|
||||
return val == NULL ? "invalid-state" : val->value_nick;
|
||||
}
|
||||
|
||||
static void
|
||||
source_fill_info (PinosSourceInfo *info, GDBusProxy *proxy)
|
||||
node_fill_info (PinosNodeInfo *info, GDBusProxy *proxy)
|
||||
{
|
||||
GHashTable *changed = g_object_get_data (G_OBJECT (proxy), "pinos-changed-properties");
|
||||
|
||||
info->id = proxy;
|
||||
info->source_path = g_dbus_proxy_get_object_path (proxy);
|
||||
info->node_path = g_dbus_proxy_get_object_path (proxy);
|
||||
|
||||
info->change_mask = 0;
|
||||
SET_STRING ("Name", name, 0);
|
||||
SET_PROPERTIES ("Properties", properties, 1);
|
||||
SET_UINT32 ("State", state, 2, PINOS_SOURCE_STATE_ERROR);
|
||||
SET_BYTES ("PossibleFormats", possible_formats, 3);
|
||||
SET_UINT32 ("State", state, 2, PINOS_NODE_STATE_ERROR);
|
||||
|
||||
if (changed)
|
||||
g_hash_table_remove_all (changed);
|
||||
}
|
||||
|
||||
static void
|
||||
source_clear_info (PinosSourceInfo *info)
|
||||
node_clear_info (PinosNodeInfo *info)
|
||||
{
|
||||
if (info->properties)
|
||||
pinos_properties_free (info->properties);
|
||||
if (info->possible_formats)
|
||||
g_bytes_unref (info->possible_formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_context_list_source_info:
|
||||
* pinos_context_list_node_info:
|
||||
* @context: a connected #PinosContext
|
||||
* @flags: extra #PinosSourceInfoFlags
|
||||
* @cb: a #PinosSourceInfoCallback
|
||||
* @flags: extra #PinosNodeInfoFlags
|
||||
* @cb: a #PinosNodeInfoCallback
|
||||
* @cancelable: a #GCancellable
|
||||
* @callback: a #GAsyncReadyCallback to call when the operation is finished
|
||||
* @user_data: user data passed to @cb
|
||||
*
|
||||
* Call @cb for each source.
|
||||
* Call @cb for each node.
|
||||
*/
|
||||
void
|
||||
pinos_context_list_source_info (PinosContext *context,
|
||||
PinosSourceInfoFlags flags,
|
||||
PinosSourceInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
pinos_context_list_node_info (PinosContext *context,
|
||||
PinosNodeInfoFlags flags,
|
||||
PinosNodeInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosContextPrivate *priv;
|
||||
GList *walk;
|
||||
|
|
@ -349,13 +346,13 @@ pinos_context_list_source_info (PinosContext *context,
|
|||
|
||||
priv = context->priv;
|
||||
|
||||
for (walk = priv->sources; walk; walk = g_list_next (walk)) {
|
||||
for (walk = priv->nodes; walk; walk = g_list_next (walk)) {
|
||||
GDBusProxy *proxy = walk->data;
|
||||
PinosSourceInfo info;
|
||||
PinosNodeInfo info;
|
||||
|
||||
source_fill_info (&info, proxy);
|
||||
node_fill_info (&info, proxy);
|
||||
cb (context, &info, user_data);
|
||||
source_clear_info (&info);
|
||||
node_clear_info (&info);
|
||||
}
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
|
@ -363,27 +360,27 @@ pinos_context_list_source_info (PinosContext *context,
|
|||
}
|
||||
|
||||
/**
|
||||
* pinos_context_get_source_info_by_id:
|
||||
* pinos_context_get_node_info_by_id:
|
||||
* @context: a connected #PinosContext
|
||||
* @id: a source id
|
||||
* @flags: extra #PinosSourceInfoFlags
|
||||
* @cb: a #PinosSourceInfoCallback
|
||||
* @id: a node id
|
||||
* @flags: extra #PinosNodeInfoFlags
|
||||
* @cb: a #PinosNodeInfoCallback
|
||||
* @cancelable: a #GCancellable
|
||||
* @callback: a #GAsyncReadyCallback to call when the operation is finished
|
||||
* @user_data: user data passed to @cb
|
||||
*
|
||||
* Call @cb for the source with @id.
|
||||
* Call @cb for the node with @id.
|
||||
*/
|
||||
void
|
||||
pinos_context_get_source_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosSourceInfoFlags flags,
|
||||
PinosSourceInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
pinos_context_get_node_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosNodeInfoFlags flags,
|
||||
PinosNodeInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosSourceInfo info;
|
||||
PinosNodeInfo info;
|
||||
GDBusProxy *proxy;
|
||||
GTask *task;
|
||||
|
||||
|
|
@ -395,53 +392,54 @@ pinos_context_get_source_info_by_id (PinosContext *context,
|
|||
|
||||
proxy = G_DBUS_PROXY (id);
|
||||
|
||||
source_fill_info (&info, proxy);
|
||||
node_fill_info (&info, proxy);
|
||||
cb (context, &info, user_data);
|
||||
source_clear_info (&info);
|
||||
node_clear_info (&info);
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_sink_state_as_string:
|
||||
* @state: a #PinosSinkState
|
||||
* pinos_direction_as_string:
|
||||
* @direction: a #PinosDirection
|
||||
*
|
||||
* Return the string representation of @state.
|
||||
* Return the string representation of @direction.
|
||||
*
|
||||
* Returns: the string representation of @state.
|
||||
* Returns: the string representation of @direction.
|
||||
*/
|
||||
const gchar *
|
||||
pinos_sink_state_as_string (PinosSinkState state)
|
||||
pinos_direction_as_string (PinosDirection direction)
|
||||
{
|
||||
GEnumValue *val;
|
||||
|
||||
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_SINK_STATE)),
|
||||
state);
|
||||
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_DIRECTION)),
|
||||
direction);
|
||||
|
||||
return val == NULL ? "invalid-state" : val->value_nick;
|
||||
return val == NULL ? "invalid-direction" : val->value_nick;
|
||||
}
|
||||
|
||||
static void
|
||||
sink_fill_info (PinosSinkInfo *info, GDBusProxy *proxy)
|
||||
port_fill_info (PinosPortInfo *info, GDBusProxy *proxy)
|
||||
{
|
||||
GHashTable *changed = g_object_get_data (G_OBJECT (proxy), "pinos-changed-properties");
|
||||
|
||||
info->id = proxy;
|
||||
info->sink_path = g_dbus_proxy_get_object_path (proxy);
|
||||
info->port_path = g_dbus_proxy_get_object_path (proxy);
|
||||
SET_UINT32 ("Direction", direction, 0, PINOS_DIRECTION_INVALID);
|
||||
SET_STRING ("Node", node_path, 0);
|
||||
|
||||
info->change_mask = 0;
|
||||
SET_STRING ("Name", name, 0);
|
||||
SET_PROPERTIES ("Properties", properties, 1);
|
||||
SET_UINT32 ("State", state, 2, PINOS_SINK_STATE_ERROR);
|
||||
SET_BYTES ("PossibleFormats", possible_formats, 3);
|
||||
SET_BYTES ("PossibleFormats", possible_formats, 2);
|
||||
|
||||
if (changed)
|
||||
g_hash_table_remove_all (changed);
|
||||
}
|
||||
|
||||
static void
|
||||
sink_clear_info (PinosSinkInfo *info)
|
||||
port_clear_info (PinosPortInfo *info)
|
||||
{
|
||||
if (info->properties)
|
||||
pinos_properties_free (info->properties);
|
||||
|
|
@ -450,20 +448,20 @@ sink_clear_info (PinosSinkInfo *info)
|
|||
}
|
||||
|
||||
/**
|
||||
* pinos_context_list_sink_info:
|
||||
* pinos_context_list_port_info:
|
||||
* @context: a connected #PinosContext
|
||||
* @flags: extra #PinosSinkInfoFlags
|
||||
* @cb: a #PinosSinkInfoCallback
|
||||
* @flags: extra #PinosPortInfoFlags
|
||||
* @cb: a #PinosPortInfoCallback
|
||||
* @cancelable: a #GCancellable
|
||||
* @callback: a #GAsyncReadyCallback to call when the operation is finished
|
||||
* @user_data: user data passed to @cb
|
||||
*
|
||||
* Call @cb for each sink.
|
||||
* Call @cb for each port.
|
||||
*/
|
||||
void
|
||||
pinos_context_list_sink_info (PinosContext *context,
|
||||
PinosSinkInfoFlags flags,
|
||||
PinosSinkInfoCallback cb,
|
||||
pinos_context_list_port_info (PinosContext *context,
|
||||
PinosPortInfoFlags flags,
|
||||
PinosPortInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
|
|
@ -479,13 +477,13 @@ pinos_context_list_sink_info (PinosContext *context,
|
|||
|
||||
priv = context->priv;
|
||||
|
||||
for (walk = priv->sinks; walk; walk = g_list_next (walk)) {
|
||||
for (walk = priv->ports; walk; walk = g_list_next (walk)) {
|
||||
GDBusProxy *proxy = walk->data;
|
||||
PinosSinkInfo info;
|
||||
PinosPortInfo info;
|
||||
|
||||
sink_fill_info (&info, proxy);
|
||||
port_fill_info (&info, proxy);
|
||||
cb (context, &info, user_data);
|
||||
sink_clear_info (&info);
|
||||
port_clear_info (&info);
|
||||
}
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
|
@ -493,27 +491,27 @@ pinos_context_list_sink_info (PinosContext *context,
|
|||
}
|
||||
|
||||
/**
|
||||
* pinos_context_get_sink_info_by_id:
|
||||
* pinos_context_get_port_info_by_id:
|
||||
* @context: a connected #PinosContext
|
||||
* @id: a sink id
|
||||
* @flags: extra #PinosSinkInfoFlags
|
||||
* @cb: a #PinosSinkInfoCallback
|
||||
* @id: a port id
|
||||
* @flags: extra #PinosPortInfoFlags
|
||||
* @cb: a #PinosPortInfoCallback
|
||||
* @cancelable: a #GCancellable
|
||||
* @callback: a #GAsyncReadyCallback to call when the operation is finished
|
||||
* @user_data: user data passed to @cb
|
||||
*
|
||||
* Call @cb for the sink with @id.
|
||||
* Call @cb for the port with @id.
|
||||
*/
|
||||
void
|
||||
pinos_context_get_sink_info_by_id (PinosContext *context,
|
||||
pinos_context_get_port_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosSinkInfoFlags flags,
|
||||
PinosSinkInfoCallback cb,
|
||||
PinosPortInfoFlags flags,
|
||||
PinosPortInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosSinkInfo info;
|
||||
PinosPortInfo info;
|
||||
GDBusProxy *proxy;
|
||||
GTask *task;
|
||||
|
||||
|
|
@ -525,9 +523,9 @@ pinos_context_get_sink_info_by_id (PinosContext *context,
|
|||
|
||||
proxy = G_DBUS_PROXY (id);
|
||||
|
||||
sink_fill_info (&info, proxy);
|
||||
port_fill_info (&info, proxy);
|
||||
cb (context, &info, user_data);
|
||||
sink_clear_info (&info);
|
||||
port_clear_info (&info);
|
||||
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
|
|
@ -559,14 +557,15 @@ channel_fill_info (PinosChannelInfo *info, GDBusProxy *proxy)
|
|||
|
||||
info->id = proxy;
|
||||
info->channel_path = g_dbus_proxy_get_object_path (proxy);
|
||||
SET_UINT32 ("Direction", direction, 2, PINOS_DIRECTION_INVALID);
|
||||
SET_STRING ("Client", client_path, 0);
|
||||
|
||||
info->change_mask = 0;
|
||||
SET_STRING ("Client", client_path, 0);
|
||||
SET_STRING ("Owner", owner_path, 1);
|
||||
SET_BYTES ("PossibleFormats", possible_formats, 2);
|
||||
SET_UINT32 ("State", state, 3, PINOS_CHANNEL_STATE_ERROR);
|
||||
SET_STRING ("Port", port_path, 0);
|
||||
SET_PROPERTIES ("Properties", properties, 1);
|
||||
SET_UINT32 ("State", state, 2, PINOS_CHANNEL_STATE_ERROR);
|
||||
SET_BYTES ("PossibleFormats", possible_formats, 3);
|
||||
SET_BYTES ("Format", format, 4);
|
||||
SET_PROPERTIES ("Properties", properties, 5);
|
||||
|
||||
if (changed)
|
||||
g_hash_table_remove_all (changed);
|
||||
|
|
@ -577,6 +576,8 @@ channel_clear_info (PinosChannelInfo *info)
|
|||
{
|
||||
if (info->possible_formats)
|
||||
g_bytes_unref (info->possible_formats);
|
||||
if (info->format)
|
||||
g_bytes_unref (info->format);
|
||||
if (info->properties)
|
||||
pinos_properties_free (info->properties);
|
||||
}
|
||||
|
|
@ -627,7 +628,7 @@ pinos_context_list_channel_info (PinosContext *context,
|
|||
/**
|
||||
* pinos_context_get_channel_info_by_id:
|
||||
* @context: a connected #PinosContext
|
||||
* @id: a source output id
|
||||
* @id: a channel id
|
||||
* @flags: extra #PinosChannelInfoFlags
|
||||
* @cb: a #PinosChannelInfoCallback
|
||||
* @cancelable: a #GCancellable
|
||||
|
|
|
|||
|
|
@ -144,190 +144,167 @@ void pinos_context_get_client_info_by_id (PinosContext *context,
|
|||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* PinosSourceState:
|
||||
* @PINOS_SOURCE_STATE_ERROR: the source is in error
|
||||
* @PINOS_SOURCE_STATE_SUSPENDED: the source is suspended, the device might
|
||||
* PinosNodeState:
|
||||
* @PINOS_NODE_STATE_ERROR: the node is in error
|
||||
* @PINOS_NODE_STATE_SUSPENDED: the node is suspended, the device might
|
||||
* be closed
|
||||
* @PINOS_SOURCE_STATE_INITIALIZING: the source is initializing, the device is
|
||||
* @PINOS_NODE_STATE_INITIALIZING: the node is initializing, the device is
|
||||
* being opened and the capabilities are queried
|
||||
* @PINOS_SOURCE_STATE_IDLE: the source is running but there is no active
|
||||
* channel
|
||||
* @PINOS_SOURCE_STATE_RUNNING: the source is running
|
||||
*
|
||||
* The different source states
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_SOURCE_STATE_ERROR = -1,
|
||||
PINOS_SOURCE_STATE_SUSPENDED = 0,
|
||||
PINOS_SOURCE_STATE_INITIALIZING = 1,
|
||||
PINOS_SOURCE_STATE_IDLE = 2,
|
||||
PINOS_SOURCE_STATE_RUNNING = 3,
|
||||
} PinosSourceState;
|
||||
|
||||
const gchar * pinos_source_state_as_string (PinosSourceState state);
|
||||
|
||||
/**
|
||||
* PinosSourceInfo:
|
||||
* @id: generic id of the source
|
||||
* @source_path: the unique path of the source, suitable for connecting
|
||||
* @change_mask: bitfield of changed fields since last call
|
||||
* @name: name the source, suitable for display
|
||||
* @properties: the properties of the source
|
||||
* @state: the current state of the source
|
||||
* @possible formats: the possible formats this source can produce
|
||||
*
|
||||
* The source information. Extra information can be added in later
|
||||
* versions.
|
||||
*/
|
||||
typedef struct {
|
||||
gpointer id;
|
||||
const char *source_path;
|
||||
guint64 change_mask;
|
||||
const char *name;
|
||||
PinosProperties *properties;
|
||||
PinosSourceState state;
|
||||
GBytes *possible_formats;
|
||||
} PinosSourceInfo;
|
||||
|
||||
/**
|
||||
* PinosSourceInfoFlags:
|
||||
* @PINOS_SOURCE_INFO_FLAGS_NONE: no flags
|
||||
* @PINOS_SOURCE_INFO_FLAGS_FORMATS: include formats
|
||||
*
|
||||
* Extra flags to pass to pinos_context_get_source_info_list.
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_SOURCE_INFO_FLAGS_NONE = 0,
|
||||
PINOS_SOURCE_INFO_FLAGS_FORMATS = (1 << 0)
|
||||
} PinosSourceInfoFlags;
|
||||
|
||||
/**
|
||||
* PinosSourceInfoCallback:
|
||||
* @c: a #PinosContext
|
||||
* @info: a #PinosSourceInfo
|
||||
* @user_data: user data
|
||||
*
|
||||
* Callback with information about the Pinos source in @info.
|
||||
*/
|
||||
typedef void (*PinosSourceInfoCallback) (PinosContext *c,
|
||||
const PinosSourceInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void pinos_context_list_source_info (PinosContext *context,
|
||||
PinosSourceInfoFlags flags,
|
||||
PinosSourceInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void pinos_context_get_source_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosSourceInfoFlags flags,
|
||||
PinosSourceInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* PinosSinkState:
|
||||
* @PINOS_SINK_STATE_ERROR: the sink is in error
|
||||
* @PINOS_SINK_STATE_SUSPENDED: the sink is suspended, the device might
|
||||
* be closed
|
||||
* @PINOS_SINK_STATE_INITIALIZING: the sink is initializing, the device is
|
||||
* being opened and the capabilities are queried
|
||||
* @PINOS_SINK_STATE_IDLE: the sink is running but there is no active
|
||||
* @PINOS_NODE_STATE_IDLE: the node is running but there is no active
|
||||
* channel
|
||||
* @PINOS_SINK_STATE_RUNNING: the sink is running
|
||||
* @PINOS_NODE_STATE_RUNNING: the node is running
|
||||
*
|
||||
* The different sink states
|
||||
* The different node states
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_SINK_STATE_ERROR = -1,
|
||||
PINOS_SINK_STATE_SUSPENDED = 0,
|
||||
PINOS_SINK_STATE_INITIALIZING = 1,
|
||||
PINOS_SINK_STATE_IDLE = 2,
|
||||
PINOS_SINK_STATE_RUNNING = 3,
|
||||
} PinosSinkState;
|
||||
PINOS_NODE_STATE_ERROR = -1,
|
||||
PINOS_NODE_STATE_SUSPENDED = 0,
|
||||
PINOS_NODE_STATE_INITIALIZING = 1,
|
||||
PINOS_NODE_STATE_IDLE = 2,
|
||||
PINOS_NODE_STATE_RUNNING = 3,
|
||||
} PinosNodeState;
|
||||
|
||||
const gchar * pinos_sink_state_as_string (PinosSinkState state);
|
||||
const gchar * pinos_node_state_as_string (PinosNodeState state);
|
||||
|
||||
/**
|
||||
* PinosSinkInfo:
|
||||
* @id: generic id of the sink
|
||||
* @sink_path: the unique path of the sink, suitable for connecting
|
||||
* PinosNodeInfo:
|
||||
* @id: generic id of the node
|
||||
* @node_path: the unique path of the node
|
||||
* @change_mask: bitfield of changed fields since last call
|
||||
* @name: name the sink, suitable for display
|
||||
* @properties: the properties of the sink
|
||||
* @state: the current state of the sink
|
||||
* @possible formats: the possible formats this sink can consume
|
||||
* @name: name the node, suitable for display
|
||||
* @properties: the properties of the node
|
||||
* @state: the current state of the node
|
||||
*
|
||||
* The sink information. Extra information can be added in later
|
||||
* The node information. Extra information can be added in later
|
||||
* versions.
|
||||
*/
|
||||
typedef struct {
|
||||
gpointer id;
|
||||
const char *sink_path;
|
||||
const char *node_path;
|
||||
guint64 change_mask;
|
||||
const char *name;
|
||||
PinosProperties *properties;
|
||||
PinosSinkState state;
|
||||
GBytes *possible_formats;
|
||||
} PinosSinkInfo;
|
||||
PinosNodeState state;
|
||||
} PinosNodeInfo;
|
||||
|
||||
/**
|
||||
* PinosSinkInfoFlags:
|
||||
* @PINOS_SINK_INFO_FLAGS_NONE: no flags
|
||||
* @PINOS_SINK_INFO_FLAGS_FORMATS: include formats
|
||||
* PinosNodeInfoFlags:
|
||||
* @PINOS_NODE_INFO_FLAGS_NONE: no flags
|
||||
*
|
||||
* Extra flags to pass to pinos_context_get_sink_info_list.
|
||||
* Extra flags to pass to pinos_context_get_node_info_list.
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_SINK_INFO_FLAGS_NONE = 0,
|
||||
PINOS_SINK_INFO_FLAGS_FORMATS = (1 << 0)
|
||||
} PinosSinkInfoFlags;
|
||||
PINOS_NODE_INFO_FLAGS_NONE = 0,
|
||||
} PinosNodeInfoFlags;
|
||||
|
||||
/**
|
||||
* PinosSinkInfoCallback:
|
||||
* PinosNodeInfoCallback:
|
||||
* @c: a #PinosContext
|
||||
* @info: a #PinosSinkInfo
|
||||
* @info: a #PinosNodeInfo
|
||||
* @user_data: user data
|
||||
*
|
||||
* Callback with information about the Pinos sink in @info.
|
||||
* Callback with information about the Pinos node in @info.
|
||||
*/
|
||||
typedef void (*PinosSinkInfoCallback) (PinosContext *c,
|
||||
const PinosSinkInfo *info,
|
||||
typedef void (*PinosNodeInfoCallback) (PinosContext *c,
|
||||
const PinosNodeInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void pinos_context_list_sink_info (PinosContext *context,
|
||||
PinosSinkInfoFlags flags,
|
||||
PinosSinkInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void pinos_context_get_sink_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosSinkInfoFlags flags,
|
||||
PinosSinkInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void pinos_context_list_node_info (PinosContext *context,
|
||||
PinosNodeInfoFlags flags,
|
||||
PinosNodeInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void pinos_context_get_node_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosNodeInfoFlags flags,
|
||||
PinosNodeInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
/**
|
||||
* PinosChannelType:
|
||||
* @PINOS_CHANNEL_TYPE_UNKNOWN: an unknown channel type
|
||||
* @PINOS_CHANNEL_TYPE_INPUT: an input channel type
|
||||
* @PINOS_CHANNEL_TYPE_OUTPUT: an output channel type
|
||||
* PinosDirection:
|
||||
* @PINOS_DIRECTION_INVALID: invalid direction
|
||||
* @PINOS_DIRECTION_INPUT: an input port/channel
|
||||
* @PINOS_DIRECTION_OUTPUT: an output port/channel
|
||||
*
|
||||
* The different channel states
|
||||
* The direction of a port or channel
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_CHANNEL_TYPE_UNKNOWN = 0,
|
||||
PINOS_CHANNEL_TYPE_INPUT = 1,
|
||||
PINOS_CHANNEL_TYPE_OUTPUT = 2,
|
||||
} PinosChannelType;
|
||||
PINOS_DIRECTION_INVALID = -1,
|
||||
PINOS_DIRECTION_INPUT = 0,
|
||||
PINOS_DIRECTION_OUTPUT = 1
|
||||
} PinosDirection;
|
||||
|
||||
const gchar * pinos_direction_as_string (PinosDirection direction);
|
||||
|
||||
/**
|
||||
* PinosPortInfo:
|
||||
* @id: generic id of the port
|
||||
* @port_path: the unique path of the port, suitable for connecting
|
||||
* @node_path: the node path of the port
|
||||
* @direction: the direction of the port
|
||||
* @change_mask: bitfield of changed fields since last call
|
||||
* @name: name the port, suitable for display
|
||||
* @properties: the properties of the port
|
||||
* @possible formats: the possible formats this port can consume
|
||||
*
|
||||
* The port information. Extra information can be added in later
|
||||
* versions.
|
||||
*/
|
||||
typedef struct {
|
||||
gpointer id;
|
||||
const char *port_path;
|
||||
const char *node_path;
|
||||
PinosDirection direction;
|
||||
guint64 change_mask;
|
||||
const char *name;
|
||||
PinosProperties *properties;
|
||||
GBytes *possible_formats;
|
||||
} PinosPortInfo;
|
||||
|
||||
/**
|
||||
* PinosPortInfoFlags:
|
||||
* @PINOS_PORT_INFO_FLAGS_NONE: no flags
|
||||
* @PINOS_PORT_INFO_FLAGS_FORMATS: include formats
|
||||
*
|
||||
* Extra flags to pass to pinos_context_get_port_info_list.
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_PORT_INFO_FLAGS_NONE = 0,
|
||||
PINOS_PORT_INFO_FLAGS_FORMATS = (1 << 0)
|
||||
} PinosPortInfoFlags;
|
||||
|
||||
/**
|
||||
* PinosPortInfoCallback:
|
||||
* @c: a #PinosContext
|
||||
* @info: a #PinosPortInfo
|
||||
* @user_data: user data
|
||||
*
|
||||
* Callback with information about the Pinos port in @info.
|
||||
*/
|
||||
typedef void (*PinosPortInfoCallback) (PinosContext *c,
|
||||
const PinosPortInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void pinos_context_list_port_info (PinosContext *context,
|
||||
PinosPortInfoFlags flags,
|
||||
PinosPortInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void pinos_context_get_port_info_by_id (PinosContext *context,
|
||||
gpointer id,
|
||||
PinosPortInfoFlags flags,
|
||||
PinosPortInfoCallback cb,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
/**
|
||||
* PinosChannelState:
|
||||
* @PINOS_CHANNEL_STATE_ERROR: the channel is in error
|
||||
* @PINOS_CHANNEL_STATE_IDLE: the channel is idle
|
||||
* @PINOS_CHANNEL_STATE_STOPPED: the channel is stopped
|
||||
* @PINOS_CHANNEL_STATE_STARTING: the channel is starting
|
||||
* @PINOS_CHANNEL_STATE_STREAMING: the channel is streaming
|
||||
*
|
||||
|
|
@ -335,7 +312,7 @@ typedef enum {
|
|||
*/
|
||||
typedef enum {
|
||||
PINOS_CHANNEL_STATE_ERROR = -1,
|
||||
PINOS_CHANNEL_STATE_IDLE = 0,
|
||||
PINOS_CHANNEL_STATE_STOPPED = 0,
|
||||
PINOS_CHANNEL_STATE_STARTING = 1,
|
||||
PINOS_CHANNEL_STATE_STREAMING = 2,
|
||||
} PinosChannelState;
|
||||
|
|
@ -346,14 +323,14 @@ const gchar * pinos_channel_state_as_string (PinosChannelState state);
|
|||
* PinosChannelInfo:
|
||||
* @id: generic id of the channel_
|
||||
* @channel_path: the unique path of the channel
|
||||
* @change_mask: bitfield of changed fields since last call
|
||||
* @direction: the channel direction
|
||||
* @client_path: the owner client
|
||||
* @owner_path: the owner source or sink path
|
||||
* @type: the channel type
|
||||
* @possible_formats: the possible formats
|
||||
* @state: the state
|
||||
* @format: when streaming, the current format
|
||||
* @change_mask: bitfield of changed fields since last call
|
||||
* @port_path: the owner port
|
||||
* @properties: the properties of the channel
|
||||
* @state: the state
|
||||
* @possible_formats: the possible formats
|
||||
* @format: when streaming, the current format
|
||||
*
|
||||
* The channel information. Extra information can be added in later
|
||||
* versions.
|
||||
|
|
@ -361,29 +338,29 @@ const gchar * pinos_channel_state_as_string (PinosChannelState state);
|
|||
typedef struct {
|
||||
gpointer id;
|
||||
const char *channel_path;
|
||||
guint64 change_mask;
|
||||
PinosDirection direction;
|
||||
const char *client_path;
|
||||
const char *owner_path;
|
||||
PinosChannelType type;
|
||||
GBytes *possible_formats;
|
||||
PinosChannelState state;
|
||||
GBytes *format;
|
||||
guint64 change_mask;
|
||||
const char *port_path;
|
||||
PinosProperties *properties;
|
||||
PinosChannelState state;
|
||||
GBytes *possible_formats;
|
||||
GBytes *format;
|
||||
} PinosChannelInfo;
|
||||
|
||||
/**
|
||||
* PinosChannelInfoFlags:
|
||||
* @PINOS_CHANNEL_INFO_FLAGS_NONE: no flags
|
||||
* @PINOS_CHANNEL_INFO_FLAGS_NO_SOURCE: don't list source channels
|
||||
* @PINOS_CHANNEL_INFO_FLAGS_NO_SINK: don't list sink channels
|
||||
* @PINOS_CHANNEL_INFO_FLAGS_NO_INPUT: don't list input channels
|
||||
* @PINOS_CHANNEL_INFO_FLAGS_NO_OUTPUT: don't list output channels
|
||||
*
|
||||
* Extra flags to pass to pinos_context_list_channel_info() and
|
||||
* pinos_context_get_channel_info_by_id().
|
||||
*/
|
||||
typedef enum {
|
||||
PINOS_CHANNEL_INFO_FLAGS_NONE = 0,
|
||||
PINOS_CHANNEL_INFO_FLAGS_NO_SOURCE = (1 << 0),
|
||||
PINOS_CHANNEL_INFO_FLAGS_NO_SINK = (1 << 1),
|
||||
PINOS_CHANNEL_INFO_FLAGS_NO_INPUT = (1 << 0),
|
||||
PINOS_CHANNEL_INFO_FLAGS_NO_OUTPUT = (1 << 1),
|
||||
} PinosChannelInfoFlags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#define PINOS_DBUS_OBJECT_PREFIX "/org/pinos"
|
||||
#define PINOS_DBUS_OBJECT_SERVER PINOS_DBUS_OBJECT_PREFIX "/server"
|
||||
#define PINOS_DBUS_OBJECT_NODE PINOS_DBUS_OBJECT_PREFIX "/node"
|
||||
#define PINOS_DBUS_OBJECT_PORT PINOS_DBUS_OBJECT_PREFIX "/port"
|
||||
#define PINOS_DBUS_OBJECT_CLIENT PINOS_DBUS_OBJECT_PREFIX "/client"
|
||||
|
||||
void pinos_init (int *argc, char **argv[]);
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ struct _PinosContextPrivate
|
|||
PinosSubscribe *subscribe;
|
||||
|
||||
GList *clients;
|
||||
GList *sources;
|
||||
GList *sinks;
|
||||
GList *nodes;
|
||||
GList *ports;
|
||||
GList *channels;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct _PinosStreamPrivate
|
|||
PinosStreamState state;
|
||||
GError *error;
|
||||
|
||||
PinosDirection direction;
|
||||
gchar *path;
|
||||
GBytes *possible_formats;
|
||||
gboolean provide;
|
||||
|
|
@ -596,14 +597,15 @@ create_failed:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
do_connect_source (PinosStream *stream)
|
||||
do_connect (PinosStream *stream)
|
||||
{
|
||||
PinosStreamPrivate *priv = stream->priv;
|
||||
PinosContext *context = priv->context;
|
||||
|
||||
g_dbus_proxy_call (context->priv->client,
|
||||
"CreateSourceChannel",
|
||||
g_variant_new ("(ss@a{sv})",
|
||||
"CreateChannel",
|
||||
g_variant_new ("(uss@a{sv})",
|
||||
priv->direction,
|
||||
(priv->path ? priv->path : ""),
|
||||
g_bytes_get_data (priv->possible_formats, NULL),
|
||||
pinos_properties_to_variant (priv->properties)),
|
||||
|
|
@ -617,21 +619,23 @@ do_connect_source (PinosStream *stream)
|
|||
}
|
||||
|
||||
/**
|
||||
* pinos_stream_connect_source:
|
||||
* pinos_stream_connect:
|
||||
* @stream: a #PinosStream
|
||||
* @source_path: the source path to connect to
|
||||
* @direction: the stream direction
|
||||
* @port_path: the port path to connect to or %NULL to get the default port
|
||||
* @flags: a #PinosStreamFlags
|
||||
* @possible_formats: (transfer full): a #GBytes with possible accepted formats
|
||||
*
|
||||
* Connect @stream for capturing from @source_path.
|
||||
* Connect @stream for input or output on @port_path.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
pinos_stream_connect_source (PinosStream *stream,
|
||||
const gchar *source_path,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats)
|
||||
pinos_stream_connect (PinosStream *stream,
|
||||
PinosDirection direction,
|
||||
const gchar *port_path,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats)
|
||||
{
|
||||
PinosStreamPrivate *priv;
|
||||
PinosContext *context;
|
||||
|
|
@ -644,8 +648,9 @@ pinos_stream_connect_source (PinosStream *stream,
|
|||
g_return_val_if_fail (pinos_context_get_state (context) == PINOS_CONTEXT_STATE_READY, FALSE);
|
||||
g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE);
|
||||
|
||||
priv->direction = direction;
|
||||
g_free (priv->path);
|
||||
priv->path = g_strdup (source_path);
|
||||
priv->path = g_strdup (port_path);
|
||||
if (priv->possible_formats)
|
||||
g_bytes_unref (priv->possible_formats);
|
||||
priv->possible_formats = possible_formats;
|
||||
|
|
@ -654,72 +659,7 @@ pinos_stream_connect_source (PinosStream *stream,
|
|||
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
|
||||
|
||||
g_main_context_invoke (context->priv->context,
|
||||
(GSourceFunc) do_connect_source,
|
||||
g_object_ref (stream));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_connect_sink (PinosStream *stream)
|
||||
{
|
||||
PinosStreamPrivate *priv = stream->priv;
|
||||
PinosContext *context = priv->context;
|
||||
|
||||
g_dbus_proxy_call (context->priv->client,
|
||||
"CreateSinkChannel",
|
||||
g_variant_new ("(ss@a{sv})",
|
||||
(priv->path ? priv->path : ""),
|
||||
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);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_stream_connect_sink:
|
||||
* @stream: a #PinosStream
|
||||
* @sink_path: the sink path to connect to
|
||||
* @flags: a #PinosStreamFlags
|
||||
* @possible_formats: (transfer full): a #GBytes with possible accepted formats
|
||||
*
|
||||
* Connect @stream for playback to @sink_path.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
pinos_stream_connect_sink (PinosStream *stream,
|
||||
const gchar *sink_path,
|
||||
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_READY, FALSE);
|
||||
g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE);
|
||||
|
||||
g_free (priv->path);
|
||||
priv->path = g_strdup (sink_path);
|
||||
if (priv->possible_formats)
|
||||
g_bytes_unref (priv->possible_formats);
|
||||
priv->possible_formats = possible_formats;
|
||||
priv->provide = FALSE;
|
||||
|
||||
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
|
||||
|
||||
g_main_context_invoke (context->priv->context,
|
||||
(GSourceFunc) do_connect_sink,
|
||||
(GSourceFunc) do_connect,
|
||||
g_object_ref (stream));
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -91,12 +91,9 @@ PinosStream * pinos_stream_new (PinosContext *context,
|
|||
PinosStreamState pinos_stream_get_state (PinosStream *stream);
|
||||
const GError * pinos_stream_get_error (PinosStream *stream);
|
||||
|
||||
gboolean pinos_stream_connect_source (PinosStream *stream,
|
||||
const gchar *source_path,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats);
|
||||
gboolean pinos_stream_connect_sink (PinosStream *stream,
|
||||
const gchar *sink_path,
|
||||
gboolean pinos_stream_connect (PinosStream *stream,
|
||||
PinosDirection direction,
|
||||
const gchar *port_path,
|
||||
PinosStreamFlags flags,
|
||||
GBytes *possible_formats);
|
||||
gboolean pinos_stream_connect_provide (PinosStream *stream,
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ notify_event (PinosSubscribe *subscribe,
|
|||
else if (g_strcmp0 (interface_name, "org.pinos.Client1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_CLIENT;
|
||||
}
|
||||
else if (g_strcmp0 (interface_name, "org.pinos.Source1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_SOURCE;
|
||||
else if (g_strcmp0 (interface_name, "org.pinos.Node1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_NODE;
|
||||
}
|
||||
else if (g_strcmp0 (interface_name, "org.pinos.Sink1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_SINK;
|
||||
else if (g_strcmp0 (interface_name, "org.pinos.Port1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_PORT;
|
||||
}
|
||||
else if (g_strcmp0 (interface_name, "org.pinos.Channel1") == 0) {
|
||||
flags = PINOS_SUBSCRIPTION_FLAG_CHANNEL;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ typedef enum {
|
|||
typedef enum {
|
||||
PINOS_SUBSCRIPTION_FLAG_DAEMON = (1 << 0),
|
||||
PINOS_SUBSCRIPTION_FLAG_CLIENT = (1 << 1),
|
||||
PINOS_SUBSCRIPTION_FLAG_SOURCE = (1 << 2),
|
||||
PINOS_SUBSCRIPTION_FLAG_SINK = (1 << 3),
|
||||
PINOS_SUBSCRIPTION_FLAG_NODE = (1 << 2),
|
||||
PINOS_SUBSCRIPTION_FLAG_PORT = (1 << 3),
|
||||
PINOS_SUBSCRIPTION_FLAG_CHANNEL = (1 << 4),
|
||||
} PinosSubscriptionFlags;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue