source-output -> channel

Rename the source-output object to channel because it is used for both
input and output.
Start the beginnings of sink support. This will make it possible to make
pinos consume data as well as provide data.
This commit is contained in:
Wim Taymans 2016-05-03 18:00:56 +02:00
parent 76afc1e330
commit 7597e48e02
23 changed files with 954 additions and 633 deletions

View file

@ -207,7 +207,7 @@ libpinoscore_@PINOS_MAJORMINOR@_la_SOURCES = \
server/daemon.c server/daemon.h \ server/daemon.c server/daemon.h \
server/source.c server/source.h \ server/source.c server/source.h \
server/client-source.c server/client-source.h \ server/client-source.c server/client-source.h \
server/source-output.c server/source-output.h \ server/channel.c server/channel.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 \
dbus/org-pinos.c dbus/org-pinos.h dbus/org-pinos.c dbus/org-pinos.h

View file

@ -148,8 +148,9 @@ pinos_context_finalize (GObject * object)
pinos_properties_free (priv->properties); pinos_properties_free (priv->properties);
g_list_free (priv->sources); g_list_free (priv->sources);
g_list_free (priv->sinks);
g_list_free (priv->clients); g_list_free (priv->clients);
g_list_free (priv->source_outputs); g_list_free (priv->channels);
g_clear_object (&priv->subscribe); g_clear_object (&priv->subscribe);
g_clear_error (&priv->error); g_clear_error (&priv->error);
@ -494,11 +495,18 @@ subscription_cb (PinosSubscribe *subscribe,
priv->sources = g_list_remove (priv->sources, object); priv->sources = g_list_remove (priv->sources, object);
break; break;
case PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT: case PINOS_SUBSCRIPTION_FLAG_SINK:
if (event == PINOS_SUBSCRIPTION_EVENT_NEW) if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
priv->source_outputs = g_list_prepend (priv->source_outputs, object); priv->sinks = g_list_prepend (priv->sinks, object);
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
priv->source_outputs = g_list_remove (priv->source_outputs, object); priv->sinks = g_list_remove (priv->sinks, object);
break;
case PINOS_SUBSCRIPTION_FLAG_CHANNEL:
if (event == PINOS_SUBSCRIPTION_EVENT_NEW)
priv->channels = g_list_prepend (priv->channels, object);
else if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE)
priv->channels = g_list_remove (priv->channels, object);
break; break;
} }

View file

@ -404,71 +404,69 @@ pinos_context_get_source_info_by_id (PinosContext *context,
} }
/** /**
* pinos_source_output_state_as_string: * pinos_sink_state_as_string:
* @state: a #PinosSourceOutputState * @state: a #PinosSinkState
* *
* Return the string representation of @state. * Return the string representation of @state.
* *
* Returns: the string representation of @state. * Returns: the string representation of @state.
*/ */
const gchar * const gchar *
pinos_source_output_state_as_string (PinosSourceOutputState state) pinos_sink_state_as_string (PinosSinkState state)
{ {
GEnumValue *val; GEnumValue *val;
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_SOURCE_OUTPUT_STATE)), val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_SINK_STATE)),
state); state);
return val == NULL ? "invalid-state" : val->value_nick; return val == NULL ? "invalid-state" : val->value_nick;
} }
static void static void
source_output_fill_info (PinosSourceOutputInfo *info, GDBusProxy *proxy) sink_fill_info (PinosSinkInfo *info, GDBusProxy *proxy)
{ {
GHashTable *changed = g_object_get_data (G_OBJECT (proxy), "pinos-changed-properties"); GHashTable *changed = g_object_get_data (G_OBJECT (proxy), "pinos-changed-properties");
info->id = proxy; info->id = proxy;
info->output_path = g_dbus_proxy_get_object_path (proxy); info->sink_path = g_dbus_proxy_get_object_path (proxy);
info->change_mask = 0; info->change_mask = 0;
SET_STRING ("Client", client_path, 0); SET_STRING ("Name", name, 0);
SET_STRING ("Source", source_path, 1); SET_PROPERTIES ("Properties", properties, 1);
SET_BYTES ("PossibleFormats", possible_formats, 2); SET_UINT32 ("State", state, 2, PINOS_SINK_STATE_ERROR);
SET_UINT32 ("State", state, 3, PINOS_SOURCE_OUTPUT_STATE_ERROR); SET_BYTES ("PossibleFormats", possible_formats, 3);
SET_BYTES ("Format", format, 4);
SET_PROPERTIES ("Properties", properties, 5);
if (changed) if (changed)
g_hash_table_remove_all (changed); g_hash_table_remove_all (changed);
} }
static void static void
source_output_clear_info (PinosSourceOutputInfo *info) sink_clear_info (PinosSinkInfo *info)
{ {
if (info->possible_formats)
g_bytes_unref (info->possible_formats);
if (info->properties) if (info->properties)
pinos_properties_free (info->properties); pinos_properties_free (info->properties);
if (info->possible_formats)
g_bytes_unref (info->possible_formats);
} }
/** /**
* pinos_context_list_source_output_info: * pinos_context_list_sink_info:
* @context: a connected #PinosContext * @context: a connected #PinosContext
* @flags: extra #PinosSourceOutputInfoFlags * @flags: extra #PinosSinkInfoFlags
* @cb: a #PinosSourceOutputInfoCallback * @cb: a #PinosSinkInfoCallback
* @cancelable: a #GCancellable * @cancelable: a #GCancellable
* @callback: a #GAsyncReadyCallback to call when the operation is finished * @callback: a #GAsyncReadyCallback to call when the operation is finished
* @user_data: user data passed to @cb * @user_data: user data passed to @cb
* *
* Call @cb for each source-output. * Call @cb for each sink.
*/ */
void void
pinos_context_list_source_output_info (PinosContext *context, pinos_context_list_sink_info (PinosContext *context,
PinosSourceOutputInfoFlags flags, PinosSinkInfoFlags flags,
PinosSourceOutputInfoCallback cb, PinosSinkInfoCallback cb,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
PinosContextPrivate *priv; PinosContextPrivate *priv;
GList *walk; GList *walk;
@ -481,13 +479,13 @@ pinos_context_list_source_output_info (PinosContext *context,
priv = context->priv; priv = context->priv;
for (walk = priv->source_outputs; walk; walk = g_list_next (walk)) { for (walk = priv->sinks; walk; walk = g_list_next (walk)) {
GDBusProxy *proxy = walk->data; GDBusProxy *proxy = walk->data;
PinosSourceOutputInfo info; PinosSinkInfo info;
source_output_fill_info (&info, proxy); sink_fill_info (&info, proxy);
cb (context, &info, user_data); cb (context, &info, user_data);
source_output_clear_info (&info); sink_clear_info (&info);
} }
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
@ -495,27 +493,27 @@ pinos_context_list_source_output_info (PinosContext *context,
} }
/** /**
* pinos_context_get_source_output_info_by_id: * pinos_context_get_sink_info_by_id:
* @context: a connected #PinosContext * @context: a connected #PinosContext
* @id: a source output id * @id: a sink id
* @flags: extra #PinosSourceOutputInfoFlags * @flags: extra #PinosSinkInfoFlags
* @cb: a #PinosSourceOutputInfoCallback * @cb: a #PinosSinkInfoCallback
* @cancelable: a #GCancellable * @cancelable: a #GCancellable
* @callback: a #GAsyncReadyCallback to call when the operation is finished * @callback: a #GAsyncReadyCallback to call when the operation is finished
* @user_data: user data passed to @cb * @user_data: user data passed to @cb
* *
* Call @cb for the source output with @id. * Call @cb for the sink with @id.
*/ */
void void
pinos_context_get_source_output_info_by_id (PinosContext *context, pinos_context_get_sink_info_by_id (PinosContext *context,
gpointer id, gpointer id,
PinosSourceOutputInfoFlags flags, PinosSinkInfoFlags flags,
PinosSourceOutputInfoCallback cb, PinosSinkInfoCallback cb,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
PinosSourceOutputInfo info; PinosSinkInfo info;
GDBusProxy *proxy; GDBusProxy *proxy;
GTask *task; GTask *task;
@ -527,9 +525,141 @@ pinos_context_get_source_output_info_by_id (PinosContext *context,
proxy = G_DBUS_PROXY (id); proxy = G_DBUS_PROXY (id);
source_output_fill_info (&info, proxy); sink_fill_info (&info, proxy);
cb (context, &info, user_data); cb (context, &info, user_data);
source_output_clear_info (&info); sink_clear_info (&info);
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
/**
* pinos_channel_state_as_string:
* @state: a #PinosChannelState
*
* Return the string representation of @state.
*
* Returns: the string representation of @state.
*/
const gchar *
pinos_channel_state_as_string (PinosChannelState state)
{
GEnumValue *val;
val = g_enum_get_value (G_ENUM_CLASS (g_type_class_ref (PINOS_TYPE_CHANNEL_STATE)),
state);
return val == NULL ? "invalid-state" : val->value_nick;
}
static void
channel_fill_info (PinosChannelInfo *info, GDBusProxy *proxy)
{
GHashTable *changed = g_object_get_data (G_OBJECT (proxy), "pinos-changed-properties");
info->id = proxy;
info->channel_path = g_dbus_proxy_get_object_path (proxy);
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_BYTES ("Format", format, 4);
SET_PROPERTIES ("Properties", properties, 5);
if (changed)
g_hash_table_remove_all (changed);
}
static void
channel_clear_info (PinosChannelInfo *info)
{
if (info->possible_formats)
g_bytes_unref (info->possible_formats);
if (info->properties)
pinos_properties_free (info->properties);
}
/**
* pinos_context_list_channel_info:
* @context: a connected #PinosContext
* @flags: extra #PinosChannelInfoFlags
* @cb: a #PinosChannelInfoCallback
* @cancelable: a #GCancellable
* @callback: a #GAsyncReadyCallback to call when the operation is finished
* @user_data: user data passed to @cb
*
* Call @cb for each channel.
*/
void
pinos_context_list_channel_info (PinosContext *context,
PinosChannelInfoFlags flags,
PinosChannelInfoCallback cb,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
PinosContextPrivate *priv;
GList *walk;
GTask *task;
g_return_if_fail (PINOS_IS_CONTEXT (context));
g_return_if_fail (cb != NULL);
task = g_task_new (context, cancellable, callback, user_data);
priv = context->priv;
for (walk = priv->channels; walk; walk = g_list_next (walk)) {
GDBusProxy *proxy = walk->data;
PinosChannelInfo info;
channel_fill_info (&info, proxy);
cb (context, &info, user_data);
channel_clear_info (&info);
}
g_task_return_boolean (task, TRUE);
g_object_unref (task);
}
/**
* pinos_context_get_channel_info_by_id:
* @context: a connected #PinosContext
* @id: a source output id
* @flags: extra #PinosChannelInfoFlags
* @cb: a #PinosChannelInfoCallback
* @cancelable: a #GCancellable
* @callback: a #GAsyncReadyCallback to call when the operation is finished
* @user_data: user data passed to @cb
*
* Call @cb for the channel with @id.
*/
void
pinos_context_get_channel_info_by_id (PinosContext *context,
gpointer id,
PinosChannelInfoFlags flags,
PinosChannelInfoCallback cb,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
PinosChannelInfo info;
GDBusProxy *proxy;
GTask *task;
g_return_if_fail (PINOS_IS_CONTEXT (context));
g_return_if_fail (id != NULL);
g_return_if_fail (cb != NULL);
task = g_task_new (context, cancellable, callback, user_data);
proxy = G_DBUS_PROXY (id);
channel_fill_info (&info, proxy);
cb (context, &info, user_data);
channel_clear_info (&info);
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
g_object_unref (task); g_object_unref (task);

View file

@ -151,7 +151,7 @@ void pinos_context_get_client_info_by_id (PinosContext *context,
* @PINOS_SOURCE_STATE_INITIALIZING: the source is initializing, the device is * @PINOS_SOURCE_STATE_INITIALIZING: the source is initializing, the device is
* being opened and the capabilities are queried * being opened and the capabilities are queried
* @PINOS_SOURCE_STATE_IDLE: the source is running but there is no active * @PINOS_SOURCE_STATE_IDLE: the source is running but there is no active
* source-output * channel
* @PINOS_SOURCE_STATE_RUNNING: the source is running * @PINOS_SOURCE_STATE_RUNNING: the source is running
* *
* The different source states * The different source states
@ -228,86 +228,189 @@ void pinos_context_get_source_info_by_id (PinosContext *context,
gpointer user_data); gpointer user_data);
/** /**
* PinosSourceState: * PinosSinkState:
* @PINOS_SOURCE_OUTPUT_STATE_ERROR: the source output is in error * @PINOS_SINK_STATE_ERROR: the sink is in error
* @PINOS_SOURCE_OUTPUT_STATE_IDLE: the source output is idle * @PINOS_SINK_STATE_SUSPENDED: the sink is suspended, the device might
* @PINOS_SOURCE_OUTPUT_STATE_STARTING: the source output is starting * be closed
* @PINOS_SOURCE_OUTPUT_STATE_STREAMING: the source output is streaming * @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
* channel
* @PINOS_SINK_STATE_RUNNING: the sink is running
* *
* The different source output states * The different sink states
*/ */
typedef enum { typedef enum {
PINOS_SOURCE_OUTPUT_STATE_ERROR = -1, PINOS_SINK_STATE_ERROR = -1,
PINOS_SOURCE_OUTPUT_STATE_IDLE = 0, PINOS_SINK_STATE_SUSPENDED = 0,
PINOS_SOURCE_OUTPUT_STATE_STARTING = 1, PINOS_SINK_STATE_INITIALIZING = 1,
PINOS_SOURCE_OUTPUT_STATE_STREAMING = 2, PINOS_SINK_STATE_IDLE = 2,
} PinosSourceOutputState; PINOS_SINK_STATE_RUNNING = 3,
} PinosSinkState;
const gchar * pinos_source_output_state_as_string (PinosSourceOutputState state); const gchar * pinos_sink_state_as_string (PinosSinkState state);
/** /**
* PinosSourceOutputInfo: * PinosSinkInfo:
* @id: generic id of the output * @id: generic id of the sink
* @path: the unique path of the output * @sink_path: the unique path of the sink, suitable for connecting
* @change_mask: bitfield of changed fields since last call * @change_mask: bitfield of changed fields since last call
* @client_path: the owner client * @name: name the sink, suitable for display
* @source_path: the source path * @properties: the properties of the sink
* @possible_formats: the possible formats * @state: the current state of the sink
* @state: the state * @possible formats: the possible formats this sink can consume
* @format: when streaming, the current format
* @properties: the properties of the source
* *
* The source information. Extra information can be added in later * The sink information. Extra information can be added in later
* versions. * versions.
*/ */
typedef struct { typedef struct {
gpointer id; gpointer id;
const char *output_path; const char *sink_path;
guint64 change_mask; guint64 change_mask;
const char *client_path; const char *name;
const char *source_path;
GBytes *possible_formats;
PinosSourceOutputState state;
GBytes *format;
PinosProperties *properties; PinosProperties *properties;
} PinosSourceOutputInfo; PinosSinkState state;
GBytes *possible_formats;
} PinosSinkInfo;
/** /**
* PinosSourceOutputInfoFlags: * PinosSinkInfoFlags:
* @PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE: no flags * @PINOS_SINK_INFO_FLAGS_NONE: no flags
* @PINOS_SINK_INFO_FLAGS_FORMATS: include formats
* *
* Extra flags to pass to pinos_context_list_source_output_info() and * Extra flags to pass to pinos_context_get_sink_info_list.
* pinos_context_get_source_output_info_by_id().
*/ */
typedef enum { typedef enum {
PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE = 0, PINOS_SINK_INFO_FLAGS_NONE = 0,
} PinosSourceOutputInfoFlags; PINOS_SINK_INFO_FLAGS_FORMATS = (1 << 0)
} PinosSinkInfoFlags;
/** /**
* PinosSourceOutputInfoCallback: * PinosSinkInfoCallback:
* @c: a #PinosContext * @c: a #PinosContext
* @info: a #PinosSourceOutputInfo * @info: a #PinosSinkInfo
* @user_data: user data * @user_data: user data
* *
* Callback with information about the Pinos source output in @info. * Callback with information about the Pinos sink in @info.
*/ */
typedef void (*PinosSourceOutputInfoCallback) (PinosContext *c, typedef void (*PinosSinkInfoCallback) (PinosContext *c,
const PinosSourceOutputInfo *info, const PinosSinkInfo *info,
gpointer user_data); gpointer user_data);
void pinos_context_list_source_output_info (PinosContext *context, void pinos_context_list_sink_info (PinosContext *context,
PinosSourceOutputInfoFlags flags, PinosSinkInfoFlags flags,
PinosSourceOutputInfoCallback cb, PinosSinkInfoCallback cb,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
void pinos_context_get_source_output_info_by_id (PinosContext *context, void pinos_context_get_sink_info_by_id (PinosContext *context,
gpointer id, gpointer id,
PinosSourceOutputInfoFlags flags, PinosSinkInfoFlags flags,
PinosSourceOutputInfoCallback cb, PinosSinkInfoCallback cb,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); 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
*
* The different channel states
*/
typedef enum {
PINOS_CHANNEL_TYPE_UNKNOWN = 0,
PINOS_CHANNEL_TYPE_INPUT = 1,
PINOS_CHANNEL_TYPE_OUTPUT = 2,
} PinosChannelType;
/**
* PinosChannelState:
* @PINOS_CHANNEL_STATE_ERROR: the channel is in error
* @PINOS_CHANNEL_STATE_IDLE: the channel is idle
* @PINOS_CHANNEL_STATE_STARTING: the channel is starting
* @PINOS_CHANNEL_STATE_STREAMING: the channel is streaming
*
* The different channel states
*/
typedef enum {
PINOS_CHANNEL_STATE_ERROR = -1,
PINOS_CHANNEL_STATE_IDLE = 0,
PINOS_CHANNEL_STATE_STARTING = 1,
PINOS_CHANNEL_STATE_STREAMING = 2,
} PinosChannelState;
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
* @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
* @properties: the properties of the channel
*
* The channel information. Extra information can be added in later
* versions.
*/
typedef struct {
gpointer id;
const char *channel_path;
guint64 change_mask;
const char *client_path;
const char *owner_path;
PinosChannelType type;
GBytes *possible_formats;
PinosChannelState state;
GBytes *format;
PinosProperties *properties;
} 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
*
* 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),
} PinosChannelInfoFlags;
/**
* PinosChannelInfoCallback:
* @c: a #PinosContext
* @info: a #PinosChannelInfo
* @user_data: user data
*
* Callback with information about the Pinos channel in @info.
*/
typedef void (*PinosChannelInfoCallback) (PinosContext *c,
const PinosChannelInfo *info,
gpointer user_data);
void pinos_context_list_channel_info (PinosContext *context,
PinosChannelInfoFlags flags,
PinosChannelInfoCallback cb,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
void pinos_context_get_channel_info_by_id (PinosContext *context,
gpointer id,
PinosChannelInfoFlags flags,
PinosChannelInfoCallback cb,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
G_END_DECLS G_END_DECLS
#endif /* __PINOS_INTROSPECT_H__ */ #endif /* __PINOS_INTROSPECT_H__ */

View file

@ -41,7 +41,8 @@ struct _PinosContextPrivate
GList *clients; GList *clients;
GList *sources; GList *sources;
GList *source_outputs; GList *sinks;
GList *channels;
}; };
void pinos_subscribe_get_proxy (PinosSubscribe *subscribe, void pinos_subscribe_get_proxy (PinosSubscribe *subscribe,

View file

@ -40,13 +40,12 @@ struct _PinosStreamPrivate
GError *error; GError *error;
gchar *source_path; gchar *source_path;
GBytes *accepted_formats; GBytes *possible_formats;
gboolean provide; gboolean provide;
GBytes *possible_formats;
GBytes *format; GBytes *format;
GDBusProxy *source_output; GDBusProxy *channel;
gboolean disconnecting; gboolean disconnecting;
PinosStreamMode mode; PinosStreamMode mode;
@ -194,9 +193,9 @@ subscription_cb (PinosSubscribe *subscribe,
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
switch (flags) { switch (flags) {
case PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT: case PINOS_SUBSCRIPTION_FLAG_CHANNEL:
if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) { if (event == PINOS_SUBSCRIPTION_EVENT_REMOVE) {
if (object == priv->source_output && !priv->disconnecting) { if (object == priv->channel && !priv->disconnecting) {
stream_set_state (stream, stream_set_state (stream,
PINOS_STREAM_STATE_ERROR, PINOS_STREAM_STATE_ERROR,
g_error_new_literal (G_IO_ERROR, g_error_new_literal (G_IO_ERROR,
@ -234,7 +233,7 @@ pinos_stream_finalize (GObject * object)
g_debug ("free stream %p", stream); g_debug ("free stream %p", stream);
g_clear_object (&priv->socket); g_clear_object (&priv->socket);
g_clear_object (&priv->source_output); g_clear_object (&priv->channel);
if (priv->possible_formats) if (priv->possible_formats)
g_bytes_unref (priv->possible_formats); g_bytes_unref (priv->possible_formats);
@ -242,8 +241,8 @@ pinos_stream_finalize (GObject * object)
g_bytes_unref (priv->format); g_bytes_unref (priv->format);
g_free (priv->source_path); g_free (priv->source_path);
if (priv->accepted_formats) if (priv->possible_formats)
g_bytes_unref (priv->accepted_formats); g_bytes_unref (priv->possible_formats);
g_clear_error (&priv->error); g_clear_error (&priv->error);
@ -491,9 +490,9 @@ pinos_stream_get_error (PinosStream *stream)
} }
static void static void
on_source_output_proxy (GObject *source_object, on_channel_proxy (GObject *source_object,
GAsyncResult *res, GAsyncResult *res,
gpointer user_data) gpointer user_data)
{ {
PinosStream *stream = user_data; PinosStream *stream = user_data;
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
@ -502,14 +501,14 @@ on_source_output_proxy (GObject *source_object,
gchar *str; gchar *str;
GError *error = NULL; GError *error = NULL;
priv->source_output = pinos_subscribe_get_proxy_finish (context->priv->subscribe, priv->channel = pinos_subscribe_get_proxy_finish (context->priv->subscribe,
res, res,
&error); &error);
if (priv->source_output == NULL) if (priv->channel == NULL)
goto source_output_failed; goto channel_failed;
/* get the source we are connected to */ /* get the source we are connected to */
v = g_dbus_proxy_get_cached_property (priv->source_output, "Source"); v = g_dbus_proxy_get_cached_property (priv->channel, "Source");
if (v) { if (v) {
gsize len; gsize len;
str = g_variant_dup_string (v, &len); str = g_variant_dup_string (v, &len);
@ -519,7 +518,7 @@ on_source_output_proxy (GObject *source_object,
priv->source_path = str; priv->source_path = str;
} }
v = g_dbus_proxy_get_cached_property (priv->source_output, "PossibleFormats"); v = g_dbus_proxy_get_cached_property (priv->channel, "PossibleFormats");
if (v) { if (v) {
gsize len; gsize len;
str = g_variant_dup_string (v, &len); str = g_variant_dup_string (v, &len);
@ -531,7 +530,7 @@ on_source_output_proxy (GObject *source_object,
g_object_notify (G_OBJECT (stream), "possible-formats"); g_object_notify (G_OBJECT (stream), "possible-formats");
} }
v = g_dbus_proxy_get_cached_property (priv->source_output, "Properties"); v = g_dbus_proxy_get_cached_property (priv->channel, "Properties");
if (v) { if (v) {
if (priv->properties) if (priv->properties)
pinos_properties_free (priv->properties); pinos_properties_free (priv->properties);
@ -546,9 +545,9 @@ on_source_output_proxy (GObject *source_object,
return; return;
source_output_failed: channel_failed:
{ {
g_warning ("failed to get source output proxy: %s", error->message); g_warning ("failed to get channel proxy: %s", error->message);
stream_set_state (stream, PINOS_STREAM_STATE_ERROR, error); stream_set_state (stream, PINOS_STREAM_STATE_ERROR, error);
g_object_unref (stream); g_object_unref (stream);
return; return;
@ -556,16 +555,16 @@ source_output_failed:
} }
static void static void
on_source_output_created (GObject *source_object, on_channel_created (GObject *source_object,
GAsyncResult *res, GAsyncResult *res,
gpointer user_data) gpointer user_data)
{ {
PinosStream *stream = user_data; PinosStream *stream = user_data;
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
PinosContext *context = priv->context; PinosContext *context = priv->context;
GVariant *ret; GVariant *ret;
GError *error = NULL; GError *error = NULL;
const gchar *source_output_path; const gchar *channel_path;
g_assert (context->priv->client == G_DBUS_PROXY (source_object)); g_assert (context->priv->client == G_DBUS_PROXY (source_object));
@ -573,14 +572,14 @@ on_source_output_created (GObject *source_object,
if (ret == NULL) if (ret == NULL)
goto create_failed; goto create_failed;
g_variant_get (ret, "(&o)", &source_output_path); g_variant_get (ret, "(&o)", &channel_path);
pinos_subscribe_get_proxy (context->priv->subscribe, pinos_subscribe_get_proxy (context->priv->subscribe,
PINOS_DBUS_SERVICE, PINOS_DBUS_SERVICE,
source_output_path, channel_path,
"org.pinos.SourceOutput1", "org.pinos.Channel1",
NULL, NULL,
on_source_output_proxy, on_channel_proxy,
stream); stream);
g_variant_unref (ret); g_variant_unref (ret);
@ -597,48 +596,48 @@ create_failed:
} }
static gboolean static gboolean
do_connect_capture (PinosStream *stream) do_connect_source (PinosStream *stream)
{ {
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
PinosContext *context = priv->context; PinosContext *context = priv->context;
g_dbus_proxy_call (context->priv->client, g_dbus_proxy_call (context->priv->client,
"CreateSourceOutput", "CreateSourceChannel",
g_variant_new ("(ss@a{sv})", g_variant_new ("(ss@a{sv})",
(priv->source_path ? priv->source_path : ""), (priv->source_path ? priv->source_path : ""),
g_bytes_get_data (priv->accepted_formats, NULL), g_bytes_get_data (priv->possible_formats, NULL),
pinos_properties_to_variant (priv->properties)), pinos_properties_to_variant (priv->properties)),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,
-1, -1,
NULL, /* GCancellable *cancellable */ NULL, /* GCancellable *cancellable */
on_source_output_created, on_channel_created,
stream); stream);
return FALSE; return FALSE;
} }
/** /**
* pinos_stream_connect_capture: * pinos_stream_connect_source:
* @stream: a #PinosStream * @stream: a #PinosStream
* @source_path: the source path to connect to * @source_path: the source path to connect to
* @flags: a #PinosStreamFlags * @flags: a #PinosStreamFlags
* @accepted_formats: (transfer full): a #GBytes with accepted formats * @possible_formats: (transfer full): a #GBytes with possible accepted formats
* *
* Connect @stream for capturing from @source_path. * Connect @stream for capturing from @source_path.
* *
* Returns: %TRUE on success. * Returns: %TRUE on success.
*/ */
gboolean gboolean
pinos_stream_connect_capture (PinosStream *stream, pinos_stream_connect_source (PinosStream *stream,
const gchar *source_path, const gchar *source_path,
PinosStreamFlags flags, PinosStreamFlags flags,
GBytes *accepted_formats) GBytes *possible_formats)
{ {
PinosStreamPrivate *priv; PinosStreamPrivate *priv;
PinosContext *context; PinosContext *context;
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
g_return_val_if_fail (accepted_formats != NULL, FALSE); g_return_val_if_fail (possible_formats != NULL, FALSE);
priv = stream->priv; priv = stream->priv;
context = priv->context; context = priv->context;
@ -647,15 +646,15 @@ pinos_stream_connect_capture (PinosStream *stream,
g_free (priv->source_path); g_free (priv->source_path);
priv->source_path = g_strdup (source_path); priv->source_path = g_strdup (source_path);
if (priv->accepted_formats) if (priv->possible_formats)
g_bytes_unref (priv->accepted_formats); g_bytes_unref (priv->possible_formats);
priv->accepted_formats = accepted_formats; priv->possible_formats = possible_formats;
priv->provide = FALSE; priv->provide = FALSE;
stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL); stream_set_state (stream, PINOS_STREAM_STATE_CONNECTING, NULL);
g_main_context_invoke (context->priv->context, g_main_context_invoke (context->priv->context,
(GSourceFunc) do_connect_capture, (GSourceFunc) do_connect_source,
g_object_ref (stream)); g_object_ref (stream));
return TRUE; return TRUE;
@ -668,14 +667,14 @@ do_connect_provide (PinosStream *stream)
PinosContext *context = priv->context; PinosContext *context = priv->context;
g_dbus_proxy_call (context->priv->client, g_dbus_proxy_call (context->priv->client,
"CreateSourceInput", "CreateUploadChannel",
g_variant_new ("(s@a{sv})", g_variant_new ("(s@a{sv})",
g_bytes_get_data (priv->possible_formats, NULL), g_bytes_get_data (priv->possible_formats, NULL),
pinos_properties_to_variant (priv->properties)), pinos_properties_to_variant (priv->properties)),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,
-1, -1,
NULL, /* GCancellable *cancellable */ NULL, /* GCancellable *cancellable */
on_source_output_created, on_channel_created,
stream); stream);
return FALSE; return FALSE;
@ -721,7 +720,7 @@ pinos_stream_connect_provide (PinosStream *stream,
} }
static void static void
on_source_output_removed (GObject *source_object, on_channel_removed (GObject *source_object,
GAsyncResult *res, GAsyncResult *res,
gpointer user_data) gpointer user_data)
{ {
@ -730,10 +729,10 @@ on_source_output_removed (GObject *source_object,
GVariant *ret; GVariant *ret;
GError *error = NULL; GError *error = NULL;
g_assert (priv->source_output == G_DBUS_PROXY (source_object)); g_assert (priv->channel == G_DBUS_PROXY (source_object));
priv->disconnecting = FALSE; priv->disconnecting = FALSE;
g_clear_object (&priv->source_output); g_clear_object (&priv->channel);
ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
if (ret == NULL) if (ret == NULL)
@ -760,13 +759,13 @@ do_disconnect (PinosStream *stream)
{ {
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
g_dbus_proxy_call (priv->source_output, g_dbus_proxy_call (priv->channel,
"Remove", "Remove",
g_variant_new ("()"), g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,
-1, -1,
NULL, /* GCancellable *cancellable */ NULL, /* GCancellable *cancellable */
on_source_output_removed, on_channel_removed,
stream); stream);
return FALSE; return FALSE;
@ -789,7 +788,7 @@ pinos_stream_disconnect (PinosStream *stream)
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
priv = stream->priv; priv = stream->priv;
g_return_val_if_fail (priv->state >= PINOS_STREAM_STATE_READY, FALSE); g_return_val_if_fail (priv->state >= PINOS_STREAM_STATE_READY, FALSE);
g_return_val_if_fail (priv->source_output != NULL, FALSE); g_return_val_if_fail (priv->channel != NULL, FALSE);
context = priv->context; context = priv->context;
g_return_val_if_fail (pinos_context_get_state (context) >= PINOS_CONTEXT_STATE_READY, FALSE); g_return_val_if_fail (pinos_context_get_state (context) >= PINOS_CONTEXT_STATE_READY, FALSE);
g_return_val_if_fail (!priv->disconnecting, FALSE); g_return_val_if_fail (!priv->disconnecting, FALSE);
@ -975,7 +974,7 @@ on_stream_started (GObject *source_object,
GError *error = NULL; GError *error = NULL;
GVariant *result, *properties; GVariant *result, *properties;
result = g_dbus_proxy_call_with_unix_fd_list_finish (priv->source_output, result = g_dbus_proxy_call_with_unix_fd_list_finish (priv->channel,
&out_fd_list, &out_fd_list,
res, res,
&error); &error);
@ -1039,7 +1038,7 @@ do_start (PinosStream *stream)
{ {
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
g_dbus_proxy_call (priv->source_output, g_dbus_proxy_call (priv->channel,
"Start", "Start",
g_variant_new ("(s)", g_bytes_get_data (priv->format, NULL)), g_variant_new ("(s)", g_bytes_get_data (priv->format, NULL)),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,
@ -1102,7 +1101,7 @@ on_stream_stopped (GObject *source_object,
GVariant *ret; GVariant *ret;
GError *error = NULL; GError *error = NULL;
ret = g_dbus_proxy_call_finish (priv->source_output, res, &error); ret = g_dbus_proxy_call_finish (priv->channel, res, &error);
if (ret == NULL) if (ret == NULL)
goto call_failed; goto call_failed;
@ -1132,7 +1131,7 @@ do_stop (PinosStream *stream)
{ {
PinosStreamPrivate *priv = stream->priv; PinosStreamPrivate *priv = stream->priv;
g_dbus_proxy_call (priv->source_output, g_dbus_proxy_call (priv->channel,
"Stop", "Stop",
g_variant_new ("()"), g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, G_DBUS_CALL_FLAGS_NONE,

View file

@ -91,10 +91,14 @@ PinosStream * pinos_stream_new (PinosContext *context,
PinosStreamState pinos_stream_get_state (PinosStream *stream); PinosStreamState pinos_stream_get_state (PinosStream *stream);
const GError * pinos_stream_get_error (PinosStream *stream); const GError * pinos_stream_get_error (PinosStream *stream);
gboolean pinos_stream_connect_capture (PinosStream *stream, gboolean pinos_stream_connect_source (PinosStream *stream,
const gchar *source_path, const gchar *source_path,
PinosStreamFlags flags, PinosStreamFlags flags,
GBytes *accepted_formats); GBytes *possible_formats);
gboolean pinos_stream_connect_sink (PinosStream *stream,
const gchar *sink_path,
PinosStreamFlags flags,
GBytes *possible_formats);
gboolean pinos_stream_connect_provide (PinosStream *stream, gboolean pinos_stream_connect_provide (PinosStream *stream,
PinosStreamFlags flags, PinosStreamFlags flags,
GBytes *possible_formats); GBytes *possible_formats);

View file

@ -108,8 +108,11 @@ notify_event (PinosSubscribe *subscribe,
else if (g_strcmp0 (interface_name, "org.pinos.Source1") == 0) { else if (g_strcmp0 (interface_name, "org.pinos.Source1") == 0) {
flags = PINOS_SUBSCRIPTION_FLAG_SOURCE; flags = PINOS_SUBSCRIPTION_FLAG_SOURCE;
} }
else if (g_strcmp0 (interface_name, "org.pinos.SourceOutput1") == 0) { else if (g_strcmp0 (interface_name, "org.pinos.Sink1") == 0) {
flags = PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT; flags = PINOS_SUBSCRIPTION_FLAG_SINK;
}
else if (g_strcmp0 (interface_name, "org.pinos.Channel1") == 0) {
flags = PINOS_SUBSCRIPTION_FLAG_CHANNEL;
} }
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0,
event, flags, data->proxy); event, flags, data->proxy);

View file

@ -48,10 +48,11 @@ typedef enum {
PINOS_SUBSCRIPTION_FLAG_DAEMON = (1 << 0), PINOS_SUBSCRIPTION_FLAG_DAEMON = (1 << 0),
PINOS_SUBSCRIPTION_FLAG_CLIENT = (1 << 1), PINOS_SUBSCRIPTION_FLAG_CLIENT = (1 << 1),
PINOS_SUBSCRIPTION_FLAG_SOURCE = (1 << 2), PINOS_SUBSCRIPTION_FLAG_SOURCE = (1 << 2),
PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT = (1 << 3), PINOS_SUBSCRIPTION_FLAG_SINK = (1 << 3),
PINOS_SUBSCRIPTION_FLAG_CHANNEL = (1 << 4),
} PinosSubscriptionFlags; } PinosSubscriptionFlags;
#define PINOS_SUBSCRIPTION_FLAGS_ALL 0xf #define PINOS_SUBSCRIPTION_FLAGS_ALL 0x1f
typedef enum { typedef enum {
PINOS_SUBSCRIPTION_EVENT_NEW = 0, PINOS_SUBSCRIPTION_EVENT_NEW = 0,

View file

@ -41,7 +41,7 @@
@short_description: Main client interface @short_description: Main client interface
Interface obtained after connecting a client and allows for Interface obtained after connecting a client and allows for
obtaining an output object from a source. obtaining an channel object from a source/sink.
--> -->
<interface name='org.pinos.Client1'> <interface name='org.pinos.Client1'>
<!-- Name: Name of the client --> <!-- Name: Name of the client -->
@ -53,32 +53,48 @@
Disconnect the client from the server. Disconnect the client from the server.
--> -->
<method name='Disconnect'/> <method name='Disconnect'/>
<!-- CreateSourceOutput: <!-- CreateSourceChannel:
@source: the Source1 object path or / for default @source: the Source1 object path or / for default
@accepted_formats: the formats that can be accepted @possible_formats: the possible formats that can be accepted
@properties: extra properties @properties: extra properties
@output: the SourceOutput1 object path @channel: the Channel object path
Create a new output for @source with given @incaps Create a new channel to capture from @source with given @possible_formats
--> -->
<method name='CreateSourceOutput'> <method name='CreateSourceChannel'>
<arg type='s' name='source' direction='in'/> <arg type='s' name='source' direction='in'/>
<arg type='s' name='accepted_formats' direction='in'/>
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='output' direction='out'/>
</method>
<!-- CreateSourceInput:
@possible_formats: the formats that can be provided
@properties: extra properties
@input: the SourceInput1 object path
Create a new source and input object with given @incaps
-->
<method name='CreateSourceInput'>
<arg type='s' name='possible_formats' direction='in'/> <arg type='s' name='possible_formats' direction='in'/>
<arg type='a{sv}' name='properties' direction='in'/> <arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='input' direction='out'/> <arg type='o' name='channel' direction='out'/>
</method> </method>
<!-- CreateSinkChannel:
@sink: the Sink1 object path or / for default
@possible_formats: the possible formats that can be provided
@properties: extra properties
@channel: the Channel object path
Create a new channel to playback to @sink with given @possible_formats
-->
<method name='CreateSinkChannel'>
<arg type='s' name='sink' direction='in'/>
<arg type='s' name='possible_formats' direction='in'/>
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='channel' direction='out'/>
</method>
<!-- CreateUploadChannel:
@possible_formats: the formats that can be provided
@properties: extra properties
@channel: the Channel object path
Create a new channel to upload a new stream
-->
<method name='CreateUploadChannel'>
<arg type='s' name='possible_formats' direction='in'/>
<arg type='a{sv}' name='properties' direction='in'/>
<arg type='o' name='channel' direction='out'/>
</method>
</interface> </interface>
<!-- <!--
@ -97,7 +113,7 @@
0 = the source is suspended, this means the device is closed 0 = the source is suspended, this means the device is closed
1 = the source is initializing 1 = the source is initializing
2 = the source is idle, this means the device is opened but 2 = the source is idle, this means the device is opened but
no source-output is consuming the data no channel is consuming the data
3 = the source is running 3 = the source is running
--> -->
<property name='State' type='u' access='read' /> <property name='State' type='u' access='read' />
@ -109,31 +125,63 @@
</interface> </interface>
<!-- <!--
org.pinos.SourceOutput1: org.pinos.Sink1:
@short_description: Interface for source output @short_description: Main sink interface
This interface is used to control the output of a source and A sink is an object that can consume media content.
start/stop the media transport.
--> -->
<interface name='org.pinos.SourceOutput1'> <interface name='org.pinos.Sink1'>
<!-- Client: the owner client of this source output --> <!-- Name: the name of the sink -->
<property name='Client' type='o' access='read' /> <property name='Name' type='s' access='read' />
<!-- Source: the source of this source output --> <!-- Properties: extra sink properties -->
<property name='Source' type='o' access='read' /> <property name='Properties' type='a{sv}' access='read' />
<!-- state: state of the sink
-1 = the sink is in error
0 = the sink is suspended, this means the device is closed
1 = the sink is initializing
2 = the sink is idle, this means the device is opened but
no channel is providing any data
3 = the sink is running
-->
<property name='State' type='u' access='read' />
<!-- PossibleFormats: <!-- PossibleFormats:
all possible formats of the source output. This is filtered
against the accepted_formats when creating the source output. The all possible formats of this sink.
-->
<property name='PossibleFormats' type='s' access='read' />
</interface>
<!--
org.pinos.Channel:
@short_description: Interface for input/output channel
This interface is used to control the input/output of a
source/sink and start/stop the media transport.
-->
<interface name='org.pinos.Channel1'>
<!-- Client: the owner client of this channel -->
<property name='Client' type='o' access='read' />
<!-- Owner: the owner source/sink of this channel -->
<property name='Owner' type='o' access='read' />
<!-- type: type of the channel
0 = input channel
1 = output channel
-->
<property name='Type' type='u' access='read' />
<!-- PossibleFormats:
all possible formats of the channel. This is filtered
against the accepted_formats when creating the channel.
--> -->
<property name='PossibleFormats' type='s' access='read' /> <property name='PossibleFormats' type='s' access='read' />
<!-- Properties: extra source output properties --> <!-- Properties: extra channel properties -->
<property name='Properties' type='a{sv}' access='read' /> <property name='Properties' type='a{sv}' access='read' />
<!-- state: state of the source output <!-- state: state of the channel
-1 = the source output is in error -1 = the channel is in error
0 = the source output is idle 0 = the channel is idle
1 = the source output is starting 1 = the channel is starting
2 = the source output is streaming 2 = the channel is streaming
--> -->
<property name='State' type='u' access='read' /> <property name='State' type='u' access='read' />
<!-- Format: the current streaming format --> <!-- Format: the current streaming format -->
@ -142,14 +190,14 @@
<!-- Start: <!-- Start:
@requested_format: requested formats @requested_format: requested formats
@fd: output file descriptor @fd: output file descriptor
@format: output format @format: channel format
@properties: output properties @properties: channel properties
Start the datatransfer of the source with @requested_format. Start the datatransfer on the channel with @requested_format.
The result is a file descriptor that can be used to get metadata The result is a file descriptor that can be used to send/receive
and media. @format contains the final media format and @properties metadata and media. @format contains the final media format and
the extra properties that describe the media format. @properties the extra properties that describe the media format.
--> -->
<method name='Start'> <method name='Start'>
<arg type='s' name='requested_format' direction='in'/> <arg type='s' name='requested_format' direction='in'/>
@ -159,12 +207,12 @@
</method> </method>
<!-- Stop: <!-- Stop:
Stop data transport Stop data transport on the channel
--> -->
<method name='Stop'/> <method name='Stop'/>
<!-- Remove: <!-- Remove:
Remove the source output Remove the channel
--> -->
<method name='Remove'/> <method name='Remove'/>

View file

@ -77,7 +77,6 @@ static void gst_pinos_sink_get_property (GObject * object, guint prop_id,
static GstStateChangeReturn static GstStateChangeReturn
gst_pinos_sink_change_state (GstElement * element, GstStateChange transition); gst_pinos_sink_change_state (GstElement * element, GstStateChange transition);
static GstCaps *gst_pinos_sink_getcaps (GstBaseSink * bsink, GstCaps * filter);
static gboolean gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps); static gboolean gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps);
static GstCaps *gst_pinos_sink_sink_fixate (GstBaseSink * bsink, static GstCaps *gst_pinos_sink_sink_fixate (GstBaseSink * bsink,
GstCaps * caps); GstCaps * caps);

View file

@ -647,7 +647,7 @@ 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_capture (pinossrc->stream, pinossrc->path, 0, accepted); pinos_stream_connect_source (pinossrc->stream, pinossrc->path, 0, accepted);
while (TRUE) { while (TRUE) {
PinosStreamState state = pinos_stream_get_state (pinossrc->stream); PinosStreamState state = pinos_stream_get_state (pinossrc->stream);

View file

@ -41,7 +41,7 @@ struct _PinosGstSourcePrivate
PinosProperties *props; PinosProperties *props;
gint n_outputs; gint n_channels;
}; };
enum { enum {
@ -420,21 +420,21 @@ on_socket_notify (GObject *gobject,
pinos_properties_free (props); pinos_properties_free (props);
} }
static PinosSourceOutput * static PinosChannel *
create_source_output (PinosSource *source, create_channel (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error) GError **error)
{ {
PinosGstSource *s = PINOS_GST_SOURCE (source); PinosGstSource *s = PINOS_GST_SOURCE (source);
PinosGstSourcePrivate *priv = s->priv; PinosGstSourcePrivate *priv = s->priv;
PinosSourceOutput *output; PinosChannel *channel;
gpointer state = NULL; gpointer state = NULL;
const gchar *key, *val; const gchar *key, *val;
if (priv->n_outputs == 0) { if (priv->n_channels == 0) {
if (!start_pipeline (s, error)) if (!start_pipeline (s, error))
return NULL; return NULL;
} }
@ -444,40 +444,40 @@ create_source_output (PinosSource *source,
pinos_properties_set (props, key, val); pinos_properties_set (props, key, val);
} }
output = PINOS_SOURCE_CLASS (pinos_gst_source_parent_class) channel = PINOS_SOURCE_CLASS (pinos_gst_source_parent_class)
->create_source_output (source, ->create_channel (source,
client_path, client_path,
format_filter, format_filter,
props, props,
prefix, prefix,
error); error);
if (output == NULL) if (channel == NULL)
goto no_output; goto no_channel;
g_signal_connect (output, g_signal_connect (channel,
"notify::socket", "notify::socket",
(GCallback) on_socket_notify, (GCallback) on_socket_notify,
source); source);
priv->n_outputs++; priv->n_channels++;
return output; return channel;
/* ERRORS */ /* ERRORS */
no_output: no_channel:
{ {
if (priv->n_outputs == 0) if (priv->n_channels == 0)
stop_pipeline (s); stop_pipeline (s);
return NULL; return NULL;
} }
} }
static gboolean static gboolean
release_source_output (PinosSource *source, release_channel (PinosSource *source,
PinosSourceOutput *output) PinosChannel *channel)
{ {
return PINOS_SOURCE_CLASS (pinos_gst_source_parent_class) return PINOS_SOURCE_CLASS (pinos_gst_source_parent_class)
->release_source_output (source, output); ->release_channel (source, channel);
} }
static void static void
@ -585,8 +585,8 @@ pinos_gst_source_class_init (PinosGstSourceClass * klass)
source_class->get_formats = get_formats; source_class->get_formats = get_formats;
source_class->set_state = set_state; source_class->set_state = set_state;
source_class->create_source_output = create_source_output; source_class->create_channel = create_channel;
source_class->release_source_output = release_source_output; source_class->release_channel = release_channel;
} }
static void static void

View file

@ -25,32 +25,32 @@
#include "pinos/client/enumtypes.h" #include "pinos/client/enumtypes.h"
#include "pinos/server/daemon.h" #include "pinos/server/daemon.h"
#include "pinos/server/source-output.h" #include "pinos/server/channel.h"
#include "pinos/dbus/org-pinos.h" #include "pinos/dbus/org-pinos.h"
struct _PinosSourceOutputPrivate struct _PinosChannelPrivate
{ {
PinosDaemon *daemon; PinosDaemon *daemon;
PinosSourceOutput1 *iface; PinosChannel1 *iface;
gchar *object_path; gchar *object_path;
gchar *client_path; gchar *client_path;
gchar *source_path; gchar *owner_path;
GBytes *possible_formats; GBytes *possible_formats;
PinosProperties *properties; PinosProperties *properties;
GBytes *requested_format; GBytes *requested_format;
PinosSourceOutputState state; PinosChannelState state;
GBytes *format; GBytes *format;
GSocket *socket; GSocket *socket;
}; };
#define PINOS_SOURCE_OUTPUT_GET_PRIVATE(obj) \ #define PINOS_CHANNEL_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_SOURCE_OUTPUT, PinosSourceOutputPrivate)) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PINOS_TYPE_CHANNEL, PinosChannelPrivate))
G_DEFINE_TYPE (PinosSourceOutput, pinos_source_output, G_TYPE_OBJECT); G_DEFINE_TYPE (PinosChannel, pinos_channel, G_TYPE_OBJECT);
enum enum
{ {
@ -58,7 +58,7 @@ enum
PROP_DAEMON, PROP_DAEMON,
PROP_OBJECT_PATH, PROP_OBJECT_PATH,
PROP_CLIENT_PATH, PROP_CLIENT_PATH,
PROP_SOURCE_PATH, PROP_OWNER_PATH,
PROP_POSSIBLE_FORMATS, PROP_POSSIBLE_FORMATS,
PROP_PROPERTIES, PROP_PROPERTIES,
PROP_REQUESTED_FORMAT, PROP_REQUESTED_FORMAT,
@ -76,13 +76,13 @@ enum
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
static void static void
pinos_source_output_get_property (GObject *_object, pinos_channel_get_property (GObject *_object,
guint prop_id, guint prop_id,
GValue *value, GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (_object); PinosChannel *channel = PINOS_CHANNEL (_object);
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
switch (prop_id) { switch (prop_id) {
case PROP_DAEMON: case PROP_DAEMON:
@ -97,8 +97,8 @@ pinos_source_output_get_property (GObject *_object,
g_value_set_string (value, priv->client_path); g_value_set_string (value, priv->client_path);
break; break;
case PROP_SOURCE_PATH: case PROP_OWNER_PATH:
g_value_set_string (value, priv->source_path); g_value_set_string (value, priv->owner_path);
break; break;
case PROP_POSSIBLE_FORMATS: case PROP_POSSIBLE_FORMATS:
@ -126,19 +126,19 @@ pinos_source_output_get_property (GObject *_object,
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (output, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (channel, prop_id, pspec);
break; break;
} }
} }
static void static void
pinos_source_output_set_property (GObject *_object, pinos_channel_set_property (GObject *_object,
guint prop_id, guint prop_id,
const GValue *value, const GValue *value,
GParamSpec *pspec) GParamSpec *pspec)
{ {
PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (_object); PinosChannel *channel = PINOS_CHANNEL (_object);
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
switch (prop_id) { switch (prop_id) {
case PROP_DAEMON: case PROP_DAEMON:
@ -154,9 +154,9 @@ pinos_source_output_set_property (GObject *_object,
g_object_set (priv->iface, "client", priv->client_path, NULL); g_object_set (priv->iface, "client", priv->client_path, NULL);
break; break;
case PROP_SOURCE_PATH: case PROP_OWNER_PATH:
priv->source_path = g_value_dup_string (value); priv->owner_path = g_value_dup_string (value);
g_object_set (priv->iface, "source", priv->source_path, NULL); g_object_set (priv->iface, "owner", priv->owner_path, NULL);
break; break;
case PROP_POSSIBLE_FORMATS: case PROP_POSSIBLE_FORMATS:
@ -184,67 +184,67 @@ pinos_source_output_set_property (GObject *_object,
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (output, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (channel, prop_id, pspec);
break; break;
} }
} }
static void static void
clear_formats (PinosSourceOutput *output) clear_formats (PinosChannel *channel)
{ {
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: clear format", output); g_debug ("channel %p: clear format", channel);
g_clear_pointer (&priv->requested_format, g_bytes_unref); g_clear_pointer (&priv->requested_format, g_bytes_unref);
g_clear_pointer (&priv->format, g_bytes_unref); g_clear_pointer (&priv->format, g_bytes_unref);
} }
static void static void
stop_transfer (PinosSourceOutput *output) stop_transfer (PinosChannel *channel)
{ {
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: stop transfer", output); g_debug ("channel %p: stop transfer", channel);
if (priv->socket) { if (priv->socket) {
g_clear_object (&priv->socket); g_clear_object (&priv->socket);
g_object_notify (G_OBJECT (output), "socket"); g_object_notify (G_OBJECT (channel), "socket");
} }
clear_formats (output); clear_formats (channel);
priv->state = PINOS_SOURCE_OUTPUT_STATE_IDLE; priv->state = PINOS_CHANNEL_STATE_IDLE;
g_object_set (priv->iface, g_object_set (priv->iface,
"state", priv->state, "state", priv->state,
NULL); NULL);
} }
static gboolean static gboolean
handle_start (PinosSourceOutput1 *interface, handle_start (PinosChannel1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
const gchar *arg_requested_format, const gchar *arg_requested_format,
gpointer user_data) gpointer user_data)
{ {
PinosSourceOutput *output = user_data; PinosChannel *channel = user_data;
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
GUnixFDList *fdlist; GUnixFDList *fdlist;
gint fd[2]; gint fd[2];
const gchar *format; const gchar *format;
priv->state = PINOS_SOURCE_OUTPUT_STATE_STARTING; priv->state = PINOS_CHANNEL_STATE_STARTING;
priv->requested_format = g_bytes_new (arg_requested_format, priv->requested_format = g_bytes_new (arg_requested_format,
strlen (arg_requested_format) + 1); strlen (arg_requested_format) + 1);
socketpair (AF_UNIX, SOCK_STREAM, 0, fd); socketpair (AF_UNIX, SOCK_STREAM, 0, fd);
g_debug ("source-output %p: handle start, fd[%d,%d]", output, fd[0], fd[1]); g_debug ("channel %p: handle start, fd[%d,%d]", channel, fd[0], fd[1]);
g_clear_object (&priv->socket); g_clear_object (&priv->socket);
priv->socket = g_socket_new_from_fd (fd[0], NULL); priv->socket = g_socket_new_from_fd (fd[0], NULL);
g_object_set_data (G_OBJECT (priv->socket), "pinos-client-path", priv->client_path); g_object_set_data (G_OBJECT (priv->socket), "pinos-client-path", priv->client_path);
g_debug ("source-output %p: notify socket %p, path %s", output, priv->socket, priv->client_path); g_debug ("channel %p: notify socket %p, path %s", channel, priv->socket, priv->client_path);
g_object_notify (G_OBJECT (output), "socket"); g_object_notify (G_OBJECT (channel), "socket");
/* the notify of the socket above should configure the format */ /* the notify of the socket above should configure the format */
if (priv->format == NULL) if (priv->format == NULL)
@ -252,8 +252,8 @@ handle_start (PinosSourceOutput1 *interface,
format = g_bytes_get_data (priv->format, NULL); format = g_bytes_get_data (priv->format, NULL);
priv->state = PINOS_SOURCE_OUTPUT_STATE_STREAMING; priv->state = PINOS_CHANNEL_STATE_STREAMING;
g_debug ("source-output %p: we are now streaming in format \"%s\"", output, format); g_debug ("channel %p: we are now streaming in format \"%s\"", channel, format);
fdlist = g_unix_fd_list_new (); fdlist = g_unix_fd_list_new ();
g_unix_fd_list_append (fdlist, fd[1], NULL); g_unix_fd_list_append (fdlist, fd[1], NULL);
@ -277,7 +277,7 @@ handle_start (PinosSourceOutput1 *interface,
/* error */ /* error */
no_format: no_format:
{ {
g_debug ("source-output %p: no format configured", output); g_debug ("channel %p: no format configured", channel);
g_dbus_method_invocation_return_dbus_error (invocation, g_dbus_method_invocation_return_dbus_error (invocation,
"org.pinos.Error", "No format"); "org.pinos.Error", "No format");
close (fd[0]); close (fd[0]);
@ -289,14 +289,14 @@ no_format:
} }
static gboolean static gboolean
handle_stop (PinosSourceOutput1 *interface, handle_stop (PinosChannel1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data) gpointer user_data)
{ {
PinosSourceOutput *output = user_data; PinosChannel *channel = user_data;
g_debug ("source-output %p: handle stop", output); g_debug ("channel %p: handle stop", channel);
stop_transfer (output); stop_transfer (channel);
g_dbus_method_invocation_return_value (invocation, NULL); g_dbus_method_invocation_return_value (invocation, NULL);
@ -304,16 +304,16 @@ handle_stop (PinosSourceOutput1 *interface,
} }
static gboolean static gboolean
handle_remove (PinosSourceOutput1 *interface, handle_remove (PinosChannel1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
gpointer user_data) gpointer user_data)
{ {
PinosSourceOutput *output = user_data; PinosChannel *channel = user_data;
g_debug ("source-output %p: handle remove", output); g_debug ("channel %p: handle remove", channel);
stop_transfer (output); stop_transfer (channel);
g_signal_emit (output, signals[SIGNAL_REMOVE], 0, NULL); g_signal_emit (channel, signals[SIGNAL_REMOVE], 0, NULL);
g_dbus_method_invocation_return_value (invocation, NULL); g_dbus_method_invocation_return_value (invocation, NULL);
@ -321,54 +321,54 @@ handle_remove (PinosSourceOutput1 *interface,
} }
static void static void
output_register_object (PinosSourceOutput *output, channel_register_object (PinosChannel *channel,
const gchar *prefix) const gchar *prefix)
{ {
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
PinosObjectSkeleton *skel; PinosObjectSkeleton *skel;
gchar *name; gchar *name;
name = g_strdup_printf ("%s/output", prefix); name = g_strdup_printf ("%s/channel", prefix);
skel = pinos_object_skeleton_new (name); skel = pinos_object_skeleton_new (name);
g_free (name); g_free (name);
pinos_object_skeleton_set_source_output1 (skel, priv->iface); pinos_object_skeleton_set_channel1 (skel, priv->iface);
g_free (priv->object_path); g_free (priv->object_path);
priv->object_path = pinos_daemon_export_uniquely (priv->daemon, G_DBUS_OBJECT_SKELETON (skel)); priv->object_path = pinos_daemon_export_uniquely (priv->daemon, G_DBUS_OBJECT_SKELETON (skel));
g_debug ("source-output %p: register object %s", output, priv->object_path); g_debug ("channel %p: register object %s", channel, priv->object_path);
} }
static void static void
output_unregister_object (PinosSourceOutput *output) channel_unregister_object (PinosChannel *channel)
{ {
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: unregister object", output); g_debug ("channel %p: unregister object", channel);
pinos_daemon_unexport (priv->daemon, priv->object_path); pinos_daemon_unexport (priv->daemon, priv->object_path);
} }
static void static void
pinos_source_output_dispose (GObject * object) pinos_channel_dispose (GObject * object)
{ {
PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (object); PinosChannel *channel = PINOS_CHANNEL (object);
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: dispose", output); g_debug ("channel %p: dispose", channel);
clear_formats (output); clear_formats (channel);
g_clear_object (&priv->socket); g_clear_object (&priv->socket);
output_unregister_object (output); channel_unregister_object (channel);
G_OBJECT_CLASS (pinos_source_output_parent_class)->dispose (object); G_OBJECT_CLASS (pinos_channel_parent_class)->dispose (object);
} }
static void static void
pinos_source_output_finalize (GObject * object) pinos_channel_finalize (GObject * object)
{ {
PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (object); PinosChannel *channel = PINOS_CHANNEL (object);
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: finalize", output); g_debug ("channel %p: finalize", channel);
if (priv->possible_formats) if (priv->possible_formats)
g_bytes_unref (priv->possible_formats); g_bytes_unref (priv->possible_formats);
if (priv->properties) if (priv->properties)
@ -377,35 +377,35 @@ pinos_source_output_finalize (GObject * object)
g_clear_object (&priv->iface); g_clear_object (&priv->iface);
g_free (priv->client_path); g_free (priv->client_path);
g_free (priv->object_path); g_free (priv->object_path);
g_free (priv->source_path); g_free (priv->owner_path);
G_OBJECT_CLASS (pinos_source_output_parent_class)->finalize (object); G_OBJECT_CLASS (pinos_channel_parent_class)->finalize (object);
} }
static void static void
pinos_source_output_constructed (GObject * object) pinos_channel_constructed (GObject * object)
{ {
PinosSourceOutput *output = PINOS_SOURCE_OUTPUT (object); PinosChannel *channel = PINOS_CHANNEL (object);
PinosSourceOutputPrivate *priv = output->priv; PinosChannelPrivate *priv = channel->priv;
g_debug ("source-output %p: constructed", output); g_debug ("channel %p: constructed", channel);
output_register_object (output, priv->object_path); channel_register_object (channel, priv->object_path);
G_OBJECT_CLASS (pinos_source_output_parent_class)->constructed (object); G_OBJECT_CLASS (pinos_channel_parent_class)->constructed (object);
} }
static void static void
pinos_source_output_class_init (PinosSourceOutputClass * klass) pinos_channel_class_init (PinosChannelClass * klass)
{ {
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosSourceOutputPrivate)); g_type_class_add_private (klass, sizeof (PinosChannelPrivate));
gobject_class->constructed = pinos_source_output_constructed; gobject_class->constructed = pinos_channel_constructed;
gobject_class->dispose = pinos_source_output_dispose; gobject_class->dispose = pinos_channel_dispose;
gobject_class->finalize = pinos_source_output_finalize; gobject_class->finalize = pinos_channel_finalize;
gobject_class->set_property = pinos_source_output_set_property; gobject_class->set_property = pinos_channel_set_property;
gobject_class->get_property = pinos_source_output_get_property; gobject_class->get_property = pinos_channel_get_property;
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_DAEMON, PROP_DAEMON,
@ -438,10 +438,10 @@ pinos_source_output_class_init (PinosSourceOutputClass * klass)
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_SOURCE_PATH, PROP_OWNER_PATH,
g_param_spec_string ("source-path", g_param_spec_string ("owner-path",
"Source Path", "Owner Path",
"The source object path", "The owner object path",
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
@ -507,52 +507,52 @@ pinos_source_output_class_init (PinosSourceOutputClass * klass)
} }
static void static void
pinos_source_output_init (PinosSourceOutput * output) pinos_channel_init (PinosChannel * channel)
{ {
PinosSourceOutputPrivate *priv = output->priv = PINOS_SOURCE_OUTPUT_GET_PRIVATE (output); PinosChannelPrivate *priv = channel->priv = PINOS_CHANNEL_GET_PRIVATE (channel);
priv->iface = pinos_source_output1_skeleton_new (); priv->iface = pinos_channel1_skeleton_new ();
g_signal_connect (priv->iface, "handle-start", (GCallback) handle_start, output); g_signal_connect (priv->iface, "handle-start", (GCallback) handle_start, channel);
g_signal_connect (priv->iface, "handle-stop", (GCallback) handle_stop, output); g_signal_connect (priv->iface, "handle-stop", (GCallback) handle_stop, channel);
g_signal_connect (priv->iface, "handle-remove", (GCallback) handle_remove, output); g_signal_connect (priv->iface, "handle-remove", (GCallback) handle_remove, channel);
priv->state = PINOS_SOURCE_OUTPUT_STATE_IDLE; priv->state = PINOS_CHANNEL_STATE_IDLE;
g_object_set (priv->iface, "state", priv->state, NULL); g_object_set (priv->iface, "state", priv->state, NULL);
g_debug ("source-output %p: new", output); g_debug ("channel %p: new", channel);
} }
/** /**
* pinos_source_output_remove: * pinos_channel_remove:
* @output: a #PinosSourceOutput * @channel: a #PinosChannel
* *
* Remove @output. This will stop the transfer on the output and * Remove @channel. This will stop the transfer on the channel and
* free the resources allocated by @output. * free the resources allocated by @channel.
*/ */
void void
pinos_source_output_remove (PinosSourceOutput *output) pinos_channel_remove (PinosChannel *channel)
{ {
g_debug ("source-output %p: remove", output); g_debug ("channel %p: remove", channel);
stop_transfer (output); stop_transfer (channel);
g_signal_emit (output, signals[SIGNAL_REMOVE], 0, NULL); g_signal_emit (channel, signals[SIGNAL_REMOVE], 0, NULL);
} }
/** /**
* pinos_source_output_get_object_path: * pinos_channel_get_object_path:
* @output: a #PinosSourceOutput * @channel: a #PinosChannel
* *
* Get the object patch of @output * Get the object patch of @channel
* *
* Returns: the object path of @source. * Returns: the object path of @source.
*/ */
const gchar * const gchar *
pinos_source_output_get_object_path (PinosSourceOutput *output) pinos_channel_get_object_path (PinosChannel *channel)
{ {
PinosSourceOutputPrivate *priv; PinosChannelPrivate *priv;
g_return_val_if_fail (PINOS_IS_SOURCE_OUTPUT (output), NULL); g_return_val_if_fail (PINOS_IS_CHANNEL (channel), NULL);
priv = output->priv; priv = channel->priv;
return priv->object_path; return priv->object_path;
} }

69
pinos/server/channel.h Normal file
View file

@ -0,0 +1,69 @@
/* 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_CHANNEL_H__
#define __PINOS_CHANNEL_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define PINOS_TYPE_CHANNEL (pinos_channel_get_type ())
#define PINOS_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_CHANNEL))
#define PINOS_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_CHANNEL))
#define PINOS_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_CHANNEL, PinosChannelClass))
#define PINOS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_CHANNEL, PinosChannel))
#define PINOS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_CHANNEL, PinosChannelClass))
#define PINOS_CHANNEL_CAST(obj) ((PinosChannel*)(obj))
#define PINOS_CHANNEL_CLASS_CAST(klass) ((PinosChannelClass*)(klass))
typedef struct _PinosChannel PinosChannel;
typedef struct _PinosChannelClass PinosChannelClass;
typedef struct _PinosChannelPrivate PinosChannelPrivate;
/**
* PinosChannel:
*
* Pinos source channel object class.
*/
struct _PinosChannel {
GObject object;
PinosChannelPrivate *priv;
};
/**
* PinosChannelClass:
*
* Pinos source channel object class.
*/
struct _PinosChannelClass {
GObjectClass parent_class;
};
/* normal GObject stuff */
GType pinos_channel_get_type (void);
void pinos_channel_remove (PinosChannel *channel);
const gchar * pinos_channel_get_object_path (PinosChannel *channel);
G_END_DECLS
#endif /* __PINOS_CHANNEL_H__ */

View file

@ -37,7 +37,7 @@ struct _PinosClientSourcePrivate
GstCaps *format; GstCaps *format;
GBytes *possible_formats; GBytes *possible_formats;
PinosSourceOutput *input; PinosChannel *channel;
}; };
G_DEFINE_TYPE (PinosClientSource, pinos_client_source, PINOS_TYPE_SOURCE); G_DEFINE_TYPE (PinosClientSource, pinos_client_source, PINOS_TYPE_SOURCE);
@ -128,7 +128,7 @@ bus_handler (GstBus *bus,
caps_str = gst_caps_to_string (caps); caps_str = gst_caps_to_string (caps);
format = g_bytes_new_take (caps_str, strlen (caps_str) + 1); format = g_bytes_new_take (caps_str, strlen (caps_str) + 1);
g_object_set (priv->input, "possible-formats", format, "format", format, NULL); g_object_set (priv->channel, "possible-formats", format, "format", format, NULL);
pinos_source_update_possible_formats (source, format); pinos_source_update_possible_formats (source, format);
pinos_source_update_format (source, format); pinos_source_update_format (source, format);
g_bytes_unref (format); g_bytes_unref (format);
@ -286,51 +286,51 @@ on_socket_notify (GObject *gobject,
GBytes *format; GBytes *format;
/* suggest what we provide */ /* suggest what we provide */
g_object_get (priv->input, "format", &format, NULL); g_object_get (priv->channel, "format", &format, NULL);
g_object_set (gobject, "format", format, NULL); g_object_set (gobject, "format", format, NULL);
g_bytes_unref (format); g_bytes_unref (format);
} }
} }
static PinosSourceOutput * static PinosChannel *
client_create_source_output (PinosSource *source, client_create_channel (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error) GError **error)
{ {
PinosClientSourcePrivate *priv = PINOS_CLIENT_SOURCE (source)->priv; PinosClientSourcePrivate *priv = PINOS_CLIENT_SOURCE (source)->priv;
PinosSourceOutput *output; PinosChannel *channel;
/* propose format of input */ /* propose format of input */
g_object_get (priv->input, "format", &format_filter, NULL); g_object_get (priv->channel, "format", &format_filter, NULL);
output = PINOS_SOURCE_CLASS (pinos_client_source_parent_class) channel = PINOS_SOURCE_CLASS (pinos_client_source_parent_class)
->create_source_output (source, ->create_channel (source,
client_path, client_path,
format_filter, format_filter,
props, props,
prefix, prefix,
error); error);
g_bytes_unref (format_filter); g_bytes_unref (format_filter);
if (output == NULL) if (channel == NULL)
return NULL; return NULL;
g_debug ("client-source %p: create output %p", source, output); g_debug ("client-source %p: create channel %p", source, channel);
g_signal_connect (output, "notify::socket", (GCallback) on_socket_notify, source); g_signal_connect (channel, "notify::socket", (GCallback) on_socket_notify, source);
return output; return channel;
} }
static gboolean static gboolean
client_release_source_output (PinosSource *source, client_release_channel (PinosSource *source,
PinosSourceOutput *output) PinosChannel *channel)
{ {
g_debug ("client-source %p: release output %p", source, output); g_debug ("client-source %p: release channel %p", source, channel);
return PINOS_SOURCE_CLASS (pinos_client_source_parent_class)->release_source_output (source, output); return PINOS_SOURCE_CLASS (pinos_client_source_parent_class)->release_channel (source, channel);
} }
static void static void
@ -353,7 +353,7 @@ client_source_finalize (GObject * object)
g_debug ("client-source %p: finalize", object); g_debug ("client-source %p: finalize", object);
g_clear_object (&priv->input); g_clear_object (&priv->channel);
g_clear_object (&priv->sink); g_clear_object (&priv->sink);
g_clear_object (&priv->src); g_clear_object (&priv->src);
g_clear_object (&priv->pipeline); g_clear_object (&priv->pipeline);
@ -407,18 +407,18 @@ on_input_socket_notify (GObject *gobject,
} }
static void static void
handle_remove_source_input (PinosSourceOutput *output, handle_remove_channel (PinosChannel *channel,
gpointer user_data) gpointer user_data)
{ {
PinosClientSource *source = user_data; PinosClientSource *source = user_data;
PinosClientSourcePrivate *priv = source->priv; PinosClientSourcePrivate *priv = source->priv;
g_debug ("client-source %p: remove source input %p", source, priv->input); g_debug ("client-source %p: remove channel %p", source, priv->channel);
g_clear_pointer (&priv->input, g_object_unref); g_clear_pointer (&priv->channel, g_object_unref);
} }
/** /**
* pinos_client_source_get_source_input: * pinos_client_source_get_channel:
* @source: a #PinosClientSource * @source: a #PinosClientSource
* @client_path: the client path * @client_path: the client path
* @format_filter: a #GBytes * @format_filter: a #GBytes
@ -426,48 +426,48 @@ handle_remove_source_input (PinosSourceOutput *output,
* @prefix: a path prefix * @prefix: a path prefix
* @error: a #GError or %NULL * @error: a #GError or %NULL
* *
* Create a new #PinosSourceOutput that can be used to send data to * Create a new #PinosChannel that can be used to send data to
* the pinos server. * the pinos server.
* *
* Returns: a new #PinosSourceOutput. * Returns: a new #PinosChannel.
*/ */
PinosSourceOutput * PinosChannel *
pinos_client_source_get_source_input (PinosClientSource *source, pinos_client_source_get_channel (PinosClientSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error) GError **error)
{ {
PinosClientSourcePrivate *priv; PinosClientSourcePrivate *priv;
g_return_val_if_fail (PINOS_IS_CLIENT_SOURCE (source), NULL); g_return_val_if_fail (PINOS_IS_CLIENT_SOURCE (source), NULL);
priv = source->priv; priv = source->priv;
if (priv->input == NULL) { if (priv->channel == NULL) {
GstCaps *caps = gst_caps_from_string (g_bytes_get_data (format_filter, NULL)); GstCaps *caps = gst_caps_from_string (g_bytes_get_data (format_filter, NULL));
gst_caps_take (&priv->format, caps); gst_caps_take (&priv->format, caps);
priv->input = PINOS_SOURCE_CLASS (pinos_client_source_parent_class) priv->channel = PINOS_SOURCE_CLASS (pinos_client_source_parent_class)
->create_source_output (PINOS_SOURCE (source), ->create_channel (PINOS_SOURCE (source),
client_path, client_path,
format_filter, format_filter,
props, props,
prefix, prefix,
error); error);
if (priv->input == NULL) if (priv->channel == NULL)
return NULL; return NULL;
g_signal_connect (priv->input, g_signal_connect (priv->channel,
"remove", "remove",
(GCallback) handle_remove_source_input, (GCallback) handle_remove_channel,
source); source);
g_debug ("client-source %p: get source input %p", source, priv->input); g_debug ("client-source %p: get source input %p", source, priv->channel);
g_signal_connect (priv->input, "notify::socket", (GCallback) on_input_socket_notify, source); g_signal_connect (priv->channel, "notify::socket", (GCallback) on_input_socket_notify, source);
} }
return g_object_ref (priv->input); return g_object_ref (priv->channel);
} }
static void static void
@ -496,8 +496,8 @@ pinos_client_source_class_init (PinosClientSourceClass * klass)
source_class->get_formats = client_get_formats; source_class->get_formats = client_get_formats;
source_class->set_state = client_set_state; source_class->set_state = client_set_state;
source_class->create_source_output = client_create_source_output; source_class->create_channel = client_create_channel;
source_class->release_source_output = client_release_source_output; source_class->release_channel = client_release_channel;
} }
static void static void

View file

@ -65,7 +65,7 @@ GType pinos_client_source_get_type (void);
PinosSource * pinos_client_source_new (PinosDaemon *daemon, PinosSource * pinos_client_source_new (PinosDaemon *daemon,
GBytes *possible_formats); GBytes *possible_formats);
PinosSourceOutput * pinos_client_source_get_source_input (PinosClientSource *source, PinosChannel * pinos_client_source_get_channel (PinosClientSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,

View file

@ -35,7 +35,7 @@ struct _PinosClientPrivate
PinosClient1 *client1; PinosClient1 *client1;
PinosFdManager *fdmanager; PinosFdManager *fdmanager;
GList *outputs; GList *channels;
}; };
#define PINOS_CLIENT_GET_PRIVATE(obj) \ #define PINOS_CLIENT_GET_PRIVATE(obj) \
@ -127,29 +127,29 @@ pinos_client_set_property (GObject *_object,
} }
static void static void
handle_remove_source_output (PinosSourceOutput *output, handle_remove_channel (PinosChannel *channel,
gpointer user_data) gpointer user_data)
{ {
PinosClient *client = user_data; PinosClient *client = user_data;
PinosClientPrivate *priv = client->priv; PinosClientPrivate *priv = client->priv;
g_debug ("client %p: remove source output %p", client, output); g_debug ("client %p: remove channel %p", client, channel);
priv->outputs = g_list_remove (priv->outputs, output); priv->channels = g_list_remove (priv->channels, channel);
g_object_unref (output); g_object_unref (channel);
} }
static gboolean static gboolean
handle_create_source_output (PinosClient1 *interface, handle_create_source_channel (PinosClient1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
const gchar *arg_source, const gchar *arg_source,
const gchar *arg_accepted_formats, const gchar *arg_accepted_formats,
GVariant *arg_properties, GVariant *arg_properties,
gpointer user_data) gpointer user_data)
{ {
PinosClient *client = user_data; PinosClient *client = user_data;
PinosClientPrivate *priv = client->priv; PinosClientPrivate *priv = client->priv;
PinosSource *source; PinosSource *source;
PinosSourceOutput *output; PinosChannel *channel;
const gchar *object_path, *sender; const gchar *object_path, *sender;
GBytes *formats; GBytes *formats;
PinosProperties *props; PinosProperties *props;
@ -170,27 +170,27 @@ handle_create_source_output (PinosClient1 *interface,
if (source == NULL) if (source == NULL)
goto no_source; goto no_source;
output = pinos_source_create_source_output (source, channel = pinos_source_create_channel (source,
priv->object_path, priv->object_path,
formats, formats,
props, props,
priv->object_path, priv->object_path,
&error); &error);
pinos_properties_free (props); pinos_properties_free (props);
g_bytes_unref (formats); g_bytes_unref (formats);
if (output == NULL) if (channel == NULL)
goto no_output; goto no_channel;
priv->outputs = g_list_prepend (priv->outputs, output); priv->channels = g_list_prepend (priv->channels, channel);
g_signal_connect (output, g_signal_connect (channel,
"remove", "remove",
(GCallback) handle_remove_source_output, (GCallback) handle_remove_channel,
client); client);
object_path = pinos_source_output_get_object_path (output); object_path = pinos_channel_get_object_path (channel);
g_debug ("client %p: add source output %p, %s", client, output, object_path); g_debug ("client %p: add channel %p, %s", client, channel, object_path);
g_dbus_method_invocation_return_value (invocation, g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", object_path)); g_variant_new ("(o)", object_path));
@ -212,9 +212,9 @@ no_source:
g_clear_error (&error); g_clear_error (&error);
return TRUE; return TRUE;
} }
no_output: no_channel:
{ {
g_debug ("client %p: could not create output %s", client, error->message); g_debug ("client %p: could not channel %s", client, error->message);
g_dbus_method_invocation_return_gerror (invocation, error); g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error); g_clear_error (&error);
return TRUE; return TRUE;
@ -222,17 +222,17 @@ no_output:
} }
static gboolean static gboolean
handle_create_source_input (PinosClient1 *interface, handle_create_upload_channel (PinosClient1 *interface,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
const gchar *arg_possible_formats, const gchar *arg_possible_formats,
GVariant *arg_properties, GVariant *arg_properties,
gpointer user_data) gpointer user_data)
{ {
PinosClient *client = user_data; PinosClient *client = user_data;
PinosClientPrivate *priv = client->priv; PinosClientPrivate *priv = client->priv;
PinosSource *source; PinosSource *source;
PinosSourceOutput *input; PinosChannel *channel;
const gchar *source_input_path, *sender; const gchar *channel_path, *sender;
GBytes *formats; GBytes *formats;
GError *error = NULL; GError *error = NULL;
PinosProperties *props; PinosProperties *props;
@ -250,34 +250,34 @@ handle_create_source_input (PinosClient1 *interface,
sender = g_dbus_method_invocation_get_sender (invocation); sender = g_dbus_method_invocation_get_sender (invocation);
props = pinos_properties_from_variant (arg_properties); props = pinos_properties_from_variant (arg_properties);
input = pinos_client_source_get_source_input (PINOS_CLIENT_SOURCE (source), channel = pinos_client_source_get_channel (PINOS_CLIENT_SOURCE (source),
priv->object_path, priv->object_path,
formats, formats,
props, props,
priv->object_path, priv->object_path,
&error); &error);
pinos_properties_free (props); pinos_properties_free (props);
if (input == NULL) if (channel == NULL)
goto no_input; goto no_channel;
g_object_set_data_full (G_OBJECT (input), g_object_set_data_full (G_OBJECT (channel),
"input-source", "channel-owner",
source, source,
g_object_unref); g_object_unref);
source_input_path = pinos_source_output_get_object_path (input); channel_path = pinos_channel_get_object_path (channel);
g_debug ("client %p: add source input %p, %s", client, input, source_input_path); g_debug ("client %p: add source channel %p, %s", client, channel, channel_path);
priv->outputs = g_list_prepend (priv->outputs, input); priv->channels = g_list_prepend (priv->channels, channel);
g_signal_connect (input, g_signal_connect (channel,
"remove", "remove",
(GCallback) handle_remove_source_output, (GCallback) handle_remove_channel,
client); client);
g_dbus_method_invocation_return_value (invocation, g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", g_variant_new ("(o)",
source_input_path)); channel_path));
return TRUE; return TRUE;
@ -296,9 +296,9 @@ no_source:
g_bytes_unref (formats); g_bytes_unref (formats);
return TRUE; return TRUE;
} }
no_input: no_channel:
{ {
g_debug ("client %p: could not create input %s", client, error->message); g_debug ("client %p: could not create channel %s", client, error->message);
g_dbus_method_invocation_return_gerror (invocation, error); g_dbus_method_invocation_return_gerror (invocation, error);
g_object_unref (source); g_object_unref (source);
g_clear_error (&error); g_clear_error (&error);
@ -337,11 +337,11 @@ client_register_object (PinosClient *client,
priv->client1 = pinos_client1_skeleton_new (); priv->client1 = pinos_client1_skeleton_new ();
pinos_client1_set_name (priv->client1, priv->sender); pinos_client1_set_name (priv->client1, priv->sender);
pinos_client1_set_properties (priv->client1, pinos_properties_to_variant (priv->properties)); pinos_client1_set_properties (priv->client1, pinos_properties_to_variant (priv->properties));
g_signal_connect (priv->client1, "handle-create-source-output", g_signal_connect (priv->client1, "handle-create-source-channel",
(GCallback) handle_create_source_output, (GCallback) handle_create_source_channel,
client); client);
g_signal_connect (priv->client1, "handle-create-source-input", g_signal_connect (priv->client1, "handle-create-upload-channel",
(GCallback) handle_create_source_input, (GCallback) handle_create_upload_channel,
client); client);
g_signal_connect (priv->client1, "handle-disconnect", g_signal_connect (priv->client1, "handle-disconnect",
(GCallback) handle_disconnect, (GCallback) handle_disconnect,
@ -367,11 +367,11 @@ client_unregister_object (PinosClient *client)
} }
static void static void
do_remove_output (PinosSourceOutput *output, do_remove_channel (PinosChannel *channel,
PinosClient *client) PinosClient *client)
{ {
g_debug ("client %p: remove output %p", client, output); g_debug ("client %p: remove channel %p", client, channel);
pinos_source_output_remove (output); pinos_channel_remove (channel);
} }
static void static void
@ -384,7 +384,7 @@ pinos_client_dispose (GObject * object)
if (priv->object_path) if (priv->object_path)
pinos_fd_manager_remove_all (priv->fdmanager, priv->object_path); pinos_fd_manager_remove_all (priv->fdmanager, priv->object_path);
g_list_foreach (priv->outputs, (GFunc) do_remove_output, client); g_list_foreach (priv->channels, (GFunc) do_remove_channel, client);
client_unregister_object (client); client_unregister_object (client);
g_clear_object (&priv->daemon); g_clear_object (&priv->daemon);

View file

@ -1,69 +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_SOURCE_OUTPUT_H__
#define __PINOS_SOURCE_OUTPUT_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define PINOS_TYPE_SOURCE_OUTPUT (pinos_source_output_get_type ())
#define PINOS_IS_SOURCE_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_SOURCE_OUTPUT))
#define PINOS_IS_SOURCE_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PINOS_TYPE_SOURCE_OUTPUT))
#define PINOS_SOURCE_OUTPUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PINOS_TYPE_SOURCE_OUTPUT, PinosSourceOutputClass))
#define PINOS_SOURCE_OUTPUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PINOS_TYPE_SOURCE_OUTPUT, PinosSourceOutput))
#define PINOS_SOURCE_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PINOS_TYPE_SOURCE_OUTPUT, PinosSourceOutputClass))
#define PINOS_SOURCE_OUTPUT_CAST(obj) ((PinosSourceOutput*)(obj))
#define PINOS_SOURCE_OUTPUT_CLASS_CAST(klass) ((PinosSourceOutputClass*)(klass))
typedef struct _PinosSourceOutput PinosSourceOutput;
typedef struct _PinosSourceOutputClass PinosSourceOutputClass;
typedef struct _PinosSourceOutputPrivate PinosSourceOutputPrivate;
/**
* PinosSourceOutput:
*
* Pinos source output object class.
*/
struct _PinosSourceOutput {
GObject object;
PinosSourceOutputPrivate *priv;
};
/**
* PinosSourceOutputClass:
*
* Pinos source output object class.
*/
struct _PinosSourceOutputClass {
GObjectClass parent_class;
};
/* normal GObject stuff */
GType pinos_source_output_get_type (void);
void pinos_source_output_remove (PinosSourceOutput *output);
const gchar * pinos_source_output_get_object_path (PinosSourceOutput *output);
G_END_DECLS
#endif /* __PINOS_SOURCE_OUTPUT_H__ */

View file

@ -44,7 +44,7 @@ struct _PinosSourcePrivate
GError *error; GError *error;
guint idle_timeout; guint idle_timeout;
GList *outputs; GList *channels;
}; };
G_DEFINE_ABSTRACT_TYPE (PinosSource, pinos_source, G_TYPE_OBJECT); G_DEFINE_ABSTRACT_TYPE (PinosSource, pinos_source, G_TYPE_OBJECT);
@ -191,10 +191,10 @@ pinos_source_constructed (GObject * object)
} }
static void static void
do_remove_output (PinosSourceOutput *output, do_remove_channel (PinosChannel *channel,
gpointer user_data) gpointer user_data)
{ {
pinos_source_output_remove (output); pinos_channel_remove (channel);
} }
static void static void
@ -203,7 +203,7 @@ pinos_source_dispose (GObject * object)
PinosSource *source = PINOS_SOURCE (object); PinosSource *source = PINOS_SOURCE (object);
PinosSourcePrivate *priv = source->priv; PinosSourcePrivate *priv = source->priv;
g_list_foreach (priv->outputs, (GFunc) do_remove_output, source); g_list_foreach (priv->channels, (GFunc) do_remove_channel, source);
source_unregister_object (source); source_unregister_object (source);
G_OBJECT_CLASS (pinos_source_parent_class)->dispose (object); G_OBJECT_CLASS (pinos_source_parent_class)->dispose (object);
@ -232,75 +232,75 @@ default_set_state (PinosSource *source,
} }
static void static void
handle_remove_output (PinosSourceOutput *output, handle_remove_channel (PinosChannel *channel,
gpointer user_data) gpointer user_data)
{ {
PinosSource *source = user_data; PinosSource *source = user_data;
pinos_source_release_source_output (source, output); pinos_source_release_channel (source, channel);
} }
static PinosSourceOutput * static PinosChannel *
default_create_source_output (PinosSource *source, default_create_channel (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error) GError **error)
{ {
PinosSourcePrivate *priv = source->priv; PinosSourcePrivate *priv = source->priv;
PinosSourceOutput *output; PinosChannel *channel;
GBytes *possible_formats; GBytes *possible_formats;
possible_formats = pinos_source_get_formats (source, format_filter, error); possible_formats = pinos_source_get_formats (source, format_filter, error);
if (possible_formats == NULL) if (possible_formats == NULL)
return NULL; return NULL;
output = g_object_new (PINOS_TYPE_SOURCE_OUTPUT, "daemon", priv->daemon, channel = g_object_new (PINOS_TYPE_CHANNEL, "daemon", priv->daemon,
"object-path", prefix, "object-path", prefix,
"client-path", client_path, "client-path", client_path,
"source-path", priv->object_path, "owner-path", priv->object_path,
"possible-formats", possible_formats, "possible-formats", possible_formats,
"properties", props, "properties", props,
NULL); NULL);
g_bytes_unref (possible_formats); g_bytes_unref (possible_formats);
if (output == NULL) if (channel == NULL)
goto no_output; goto no_channel;
g_signal_connect (output, g_signal_connect (channel,
"remove", "remove",
(GCallback) handle_remove_output, (GCallback) handle_remove_channel,
source); source);
priv->outputs = g_list_prepend (priv->outputs, output); priv->channels = g_list_prepend (priv->channels, channel);
return g_object_ref (output); return g_object_ref (channel);
/* ERRORS */ /* ERRORS */
no_output: no_channel:
{ {
if (error) if (error)
*error = g_error_new (G_IO_ERROR, *error = g_error_new (G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
"Could not create a source output"); "Could not create channel");
return NULL; return NULL;
} }
} }
static gboolean static gboolean
default_release_source_output (PinosSource *source, default_release_channel (PinosSource *source,
PinosSourceOutput *output) PinosChannel *channel)
{ {
PinosSourcePrivate *priv = source->priv; PinosSourcePrivate *priv = source->priv;
GList *find; GList *find;
find = g_list_find (priv->outputs, output); find = g_list_find (priv->channels, channel);
if (find == NULL) if (find == NULL)
return FALSE; return FALSE;
priv->outputs = g_list_delete_link (priv->outputs, find); priv->channels = g_list_delete_link (priv->channels, find);
g_object_unref (output); g_object_unref (channel);
return TRUE; return TRUE;
} }
@ -370,8 +370,8 @@ pinos_source_class_init (PinosSourceClass * klass)
klass->set_state = default_set_state; klass->set_state = default_set_state;
klass->create_source_output = default_create_source_output; klass->create_channel = default_create_channel;
klass->release_source_output = default_release_source_output; klass->release_channel = default_release_channel;
} }
static void static void
@ -562,7 +562,7 @@ pinos_source_report_busy (PinosSource *source)
* @formats: a #GBytes * @formats: a #GBytes
* *
* Update the possible formats in @source to @formats. This function also * Update the possible formats in @source to @formats. This function also
* updates the possible formats of the outputs. * updates the possible formats of the channels.
*/ */
void void
pinos_source_update_possible_formats (PinosSource *source, GBytes *formats) pinos_source_update_possible_formats (PinosSource *source, GBytes *formats)
@ -578,7 +578,7 @@ pinos_source_update_possible_formats (PinosSource *source, GBytes *formats)
g_bytes_get_data (formats, NULL), g_bytes_get_data (formats, NULL),
NULL); NULL);
for (walk = priv->outputs; walk; walk = g_list_next (walk)) for (walk = priv->channels; walk; walk = g_list_next (walk))
g_object_set (walk->data, "possible-formats", formats, NULL); g_object_set (walk->data, "possible-formats", formats, NULL);
} }
@ -588,7 +588,7 @@ pinos_source_update_possible_formats (PinosSource *source, GBytes *formats)
* @format: a #GBytes * @format: a #GBytes
* *
* Update the current format in @source to @format. This function also * Update the current format in @source to @format. This function also
* updates the current format of the outputs. * updates the current format of the channels.
*/ */
void void
pinos_source_update_format (PinosSource *source, GBytes *format) pinos_source_update_format (PinosSource *source, GBytes *format)
@ -599,12 +599,12 @@ pinos_source_update_format (PinosSource *source, GBytes *format)
g_return_if_fail (PINOS_IS_SOURCE (source)); g_return_if_fail (PINOS_IS_SOURCE (source));
priv = source->priv; priv = source->priv;
for (walk = priv->outputs; walk; walk = g_list_next (walk)) for (walk = priv->channels; walk; walk = g_list_next (walk))
g_object_set (walk->data, "format", format, NULL); g_object_set (walk->data, "format", format, NULL);
} }
/** /**
* pinos_source_create_source_output: * pinos_source_create_channel:
* @source: a #PinosSource * @source: a #PinosSource
* @client_path: the client path * @client_path: the client path
* @format_filter: a #GBytes * @format_filter: a #GBytes
@ -612,33 +612,33 @@ pinos_source_update_format (PinosSource *source, GBytes *format)
* @prefix: a prefix * @prefix: a prefix
* @error: a #GError or %NULL * @error: a #GError or %NULL
* *
* Create a new #PinosSourceOutput for @source. * Create a new #PinosChannel for @source.
* *
* Returns: a new #PinosSourceOutput or %NULL, in wich case @error will contain * Returns: a new #PinosChannel or %NULL, in wich case @error will contain
* more information about the error. * more information about the error.
*/ */
PinosSourceOutput * PinosChannel *
pinos_source_create_source_output (PinosSource *source, pinos_source_create_channel (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error) GError **error)
{ {
PinosSourceClass *klass; PinosSourceClass *klass;
PinosSourceOutput *res; PinosChannel *res;
g_return_val_if_fail (PINOS_IS_SOURCE (source), NULL); g_return_val_if_fail (PINOS_IS_SOURCE (source), NULL);
klass = PINOS_SOURCE_GET_CLASS (source); klass = PINOS_SOURCE_GET_CLASS (source);
if (klass->create_source_output) { if (klass->create_channel) {
res = klass->create_source_output (source, client_path, format_filter, props, prefix, error); res = klass->create_channel (source, client_path, format_filter, props, prefix, error);
} else { } else {
if (error) { if (error) {
*error = g_error_new (G_IO_ERROR, *error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED, G_IO_ERROR_NOT_SUPPORTED,
"Create SourceOutput not implemented"); "CreateChannel not implemented");
} }
res = NULL; res = NULL;
} }
@ -647,28 +647,28 @@ pinos_source_create_source_output (PinosSource *source,
} }
/** /**
* pinos_source_release_source_output: * pinos_source_release_channel:
* @source: a #PinosSource * @source: a #PinosSource
* @output: a #PinosSourceOutput * @channel: a #PinosChannel
* *
* Release the @output in @source. * Release the @channel in @source.
* *
* Returns: %TRUE on success. * Returns: %TRUE on success.
*/ */
gboolean gboolean
pinos_source_release_source_output (PinosSource *source, pinos_source_release_channel (PinosSource *source,
PinosSourceOutput *output) PinosChannel *channel)
{ {
PinosSourceClass *klass; PinosSourceClass *klass;
gboolean res; gboolean res;
g_return_val_if_fail (PINOS_IS_SOURCE (source), FALSE); g_return_val_if_fail (PINOS_IS_SOURCE (source), FALSE);
g_return_val_if_fail (PINOS_IS_SOURCE_OUTPUT (output), FALSE); g_return_val_if_fail (PINOS_IS_CHANNEL (channel), FALSE);
klass = PINOS_SOURCE_GET_CLASS (source); klass = PINOS_SOURCE_GET_CLASS (source);
if (klass->release_source_output) if (klass->release_channel)
res = klass->release_source_output (source, output); res = klass->release_channel (source, channel);
else else
res = FALSE; res = FALSE;

View file

@ -29,7 +29,7 @@ typedef struct _PinosSourceClass PinosSourceClass;
typedef struct _PinosSourcePrivate PinosSourcePrivate; typedef struct _PinosSourcePrivate PinosSourcePrivate;
#include <pinos/client/introspect.h> #include <pinos/client/introspect.h>
#include <pinos/server/source-output.h> #include <pinos/server/channel.h>
#define PINOS_TYPE_SOURCE (pinos_source_get_type ()) #define PINOS_TYPE_SOURCE (pinos_source_get_type ())
#define PINOS_IS_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_SOURCE)) #define PINOS_IS_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PINOS_TYPE_SOURCE))
@ -55,8 +55,8 @@ struct _PinosSource {
* PinosSourceClass: * PinosSourceClass:
* @get_formats: called to get a list of supported formats from the source * @get_formats: called to get a list of supported formats from the source
* @set_state: called to change the current state of the source * @set_state: called to change the current state of the source
* @create_source_output: called to create a new source-output object * @create_channel: called to create a new channel object
* @release_source_output: called to release a source-output object * @release_channel: called to release a channel object
* *
* Pinos source object class. * Pinos source object class.
*/ */
@ -69,14 +69,14 @@ struct _PinosSourceClass {
gboolean (*set_state) (PinosSource *source, PinosSourceState); gboolean (*set_state) (PinosSource *source, PinosSourceState);
PinosSourceOutput * (*create_source_output) (PinosSource *source, PinosChannel * (*create_channel) (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error); GError **error);
gboolean (*release_source_output) (PinosSource *source, gboolean (*release_channel) (PinosSource *source,
PinosSourceOutput *output); PinosChannel *channel);
}; };
/* normal GObject stuff */ /* normal GObject stuff */
@ -97,14 +97,14 @@ void pinos_source_report_busy (PinosSource *source);
void pinos_source_update_possible_formats (PinosSource *source, GBytes *formats); void pinos_source_update_possible_formats (PinosSource *source, GBytes *formats);
void pinos_source_update_format (PinosSource *source, GBytes *format); void pinos_source_update_format (PinosSource *source, GBytes *format);
PinosSourceOutput * pinos_source_create_source_output (PinosSource *source, PinosChannel * pinos_source_create_channel (PinosSource *source,
const gchar *client_path, const gchar *client_path,
GBytes *format_filter, GBytes *format_filter,
PinosProperties *props, PinosProperties *props,
const gchar *prefix, const gchar *prefix,
GError **error); GError **error);
gboolean pinos_source_release_source_output (PinosSource *source, gboolean pinos_source_release_channel (PinosSource *source,
PinosSourceOutput *output); PinosChannel *channel);
G_END_DECLS G_END_DECLS

View file

@ -143,7 +143,7 @@ on_state_notify (GObject *gobject,
g_signal_connect (stream, "notify::socket", (GCallback) on_socket_notify, stream); g_signal_connect (stream, "notify::socket", (GCallback) on_socket_notify, stream);
format = g_bytes_new_static (ANY_CAPS, strlen (ANY_CAPS) + 1); format = g_bytes_new_static (ANY_CAPS, strlen (ANY_CAPS) + 1);
pinos_stream_connect_capture (stream, NULL, 0, format); pinos_stream_connect_source (stream, NULL, 0, format);
g_bytes_unref (format); g_bytes_unref (format);
break; break;
} }

View file

@ -152,17 +152,33 @@ dump_source_info (PinosContext *c, const PinosSourceInfo *info, gpointer user_da
} }
static void static void
dump_source_output_info (PinosContext *c, const PinosSourceOutputInfo *info, gpointer user_data) dump_sink_info (PinosContext *c, const PinosSinkInfo *info, gpointer user_data)
{ {
DumpData *data = user_data; DumpData *data = user_data;
g_print ("\tid: %p\n", info->id); g_print ("\tid: %p\n", info->id);
g_print ("\toutput-path: \"%s\"\n", info->output_path); g_print ("\tsource-path: \"%s\"\n", info->sink_path);
if (data->print_all) {
g_print ("%c\tname: \"%s\"\n", MARK_CHANGE (0), info->name);
print_properties (info->properties, MARK_CHANGE (1));
g_print ("%c\tstate: \"%s\"\n", MARK_CHANGE (2), pinos_sink_state_as_string (info->state));
print_formats ("possible formats", info->possible_formats, MARK_CHANGE (3));
}
}
static void
dump_channel_info (PinosContext *c, const PinosChannelInfo *info, gpointer user_data)
{
DumpData *data = user_data;
g_print ("\tid: %p\n", info->id);
g_print ("\tchannel-path: \"%s\"\n", info->channel_path);
if (data->print_all) { if (data->print_all) {
g_print ("%c\tclient-path: \"%s\"\n", MARK_CHANGE (0), info->client_path); g_print ("%c\tclient-path: \"%s\"\n", MARK_CHANGE (0), info->client_path);
g_print ("%c\tsource-path: \"%s\"\n", MARK_CHANGE (1), info->source_path); g_print ("%c\towner-path: \"%s\"\n", MARK_CHANGE (1), info->owner_path);
print_formats ("possible-formats", info->possible_formats, MARK_CHANGE (2)); print_formats ("possible-formats", info->possible_formats, MARK_CHANGE (2));
g_print ("%c\tstate: \"%s\"\n", MARK_CHANGE (3), pinos_source_output_state_as_string (info->state)); g_print ("%c\tstate: \"%s\"\n", MARK_CHANGE (3), pinos_channel_state_as_string (info->state));
print_formats ("format", info->format, MARK_CHANGE (4)); print_formats ("format", info->format, MARK_CHANGE (4));
print_properties (info->properties, MARK_CHANGE (5)); print_properties (info->properties, MARK_CHANGE (5));
} }
@ -198,14 +214,23 @@ dump_object (PinosContext *context, gpointer id, PinosSubscriptionFlags flags,
info_ready, info_ready,
data); data);
} }
else if (flags & PINOS_SUBSCRIPTION_FLAG_SOURCE_OUTPUT) { else if (flags & PINOS_SUBSCRIPTION_FLAG_SINK) {
pinos_context_get_source_output_info_by_id (context, pinos_context_get_sink_info_by_id (context,
id, id,
PINOS_SOURCE_OUTPUT_INFO_FLAGS_NONE, PINOS_SINK_INFO_FLAGS_FORMATS,
dump_source_output_info, dump_sink_info,
NULL, NULL,
info_ready, info_ready,
data); data);
}
else if (flags & PINOS_SUBSCRIPTION_FLAG_CHANNEL) {
pinos_context_get_channel_info_by_id (context,
id,
PINOS_CHANNEL_INFO_FLAGS_NONE,
dump_channel_info,
NULL,
info_ready,
data);
} }
} }