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:
Wim Taymans 2016-05-06 13:01:52 +02:00
parent b885d40390
commit ba4ef9b5d9
35 changed files with 1939 additions and 2120 deletions

View file

@ -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,

View file

@ -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:

View file

@ -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

View file

@ -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;
/**

View file

@ -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[]);

View file

@ -40,8 +40,8 @@ struct _PinosContextPrivate
PinosSubscribe *subscribe;
GList *clients;
GList *sources;
GList *sinks;
GList *nodes;
GList *ports;
GList *channels;
};

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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;