support remote sources

Watch client object-manager and keep the remote source object in a
SourceProvider object. Keep a list of all sources in the daemon.

Handle the Client CreateSourceOutput by calling the method on a
registered source in the daemon.

Pass GDBusObject in the subscription signal so that we can get to more
details.
This commit is contained in:
Wim Taymans 2015-04-20 15:03:14 +02:00
parent 752494621c
commit 93c246c4ce
14 changed files with 531 additions and 70 deletions

View File

@ -84,11 +84,12 @@ client/pv-enumtypes.c: $(enumtypesincludes) client/pv-enumtypes.h
dbus/org-pulsevideo.c: dbus/org-pulsevideo.h
dbus/org-pulsevideo.h: dbus/org.pulsevideo.xml
$(AM_V_GEN) $(GDBUS_CODEGEN) \
--c-generate-object-manager \
--interface-prefix org.pulsevideo. \
--generate-c-code dbus/org-pulsevideo \
--generate-docbook ../doc/org-pulsevideo \
--c-namespace Pv dbus/org.pulsevideo.xml
--c-namespace Pv dbus/org.pulsevideo.xml \
--c-generate-object-manager
built_header_make = client/pv-enumtypes.h dbus/org-pulsevideo.h
built_source_make = client/pv-enumtypes.c dbus/org-pulsevideo.c
@ -192,6 +193,7 @@ lib_LTLIBRARIES += libpulsevideocore-@PV_MAJORMINOR@.la
# Pure core stuff
libpulsevideocore_@PV_MAJORMINOR@_la_SOURCES = \
server/pv-client.c server/pv-client.h \
server/pv-source-provider.c server/pv-source-provider.h \
server/pv-daemon.c server/pv-daemon.h \
modules/v4l2/pv-v4l2-source.c

View File

@ -92,6 +92,28 @@ pv_source_set_property (GObject *_object,
break;
}
}
static gboolean
handle_create_source_output (PvSource1 *interface,
GDBusMethodInvocation *invocation,
GVariant *arg_properties,
gpointer user_data)
{
PvSource *source = user_data;
PvSourcePrivate *priv = source->priv;
PvSourceOutput *output;
const gchar *object_path;
output = pv_source_create_source_output (source, arg_properties, priv->object_path);
object_path = pv_source_output_get_object_path (output);
pv_source1_complete_create_source_output (interface,
invocation,
object_path);
return TRUE;
}
static void
source_register_object (PvSource *source)
{
@ -103,6 +125,7 @@ source_register_object (PvSource *source)
PvSource1 *iface;
iface = pv_source1_skeleton_new ();
g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, source);
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
g_object_unref (iface);
}

View File

@ -327,6 +327,8 @@ on_source_output_created (GObject *source_object,
&priv->source_output_sender, &priv->source_output_path, res, &error))
goto create_failed;
g_print ("got source-output %s %s\n", priv->source_output_sender, priv->source_output_path);
pv_source_output1_proxy_new (pv_context_get_connection (context),
G_DBUS_PROXY_FLAGS_NONE,
priv->source_output_sender,

View File

@ -68,19 +68,19 @@ notify_subscription (PvSubscribe *subscribe,
if ((interface == NULL && pv_object_peek_client1 (PV_OBJECT (object))) ||
PV_IS_CLIENT1_PROXY (interface))
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
PV_SUBSCRIPTION_FLAGS_CLIENT, g_dbus_object_get_object_path (object));
PV_SUBSCRIPTION_FLAGS_CLIENT, object);
}
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE) {
if ((interface == NULL && pv_object_peek_source1 (PV_OBJECT (object))) ||
PV_IS_SOURCE1_PROXY (interface))
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
PV_SUBSCRIPTION_FLAGS_SOURCE, g_dbus_object_get_object_path (object));
PV_SUBSCRIPTION_FLAGS_SOURCE, object);
}
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT) {
if ((interface == NULL && pv_object_peek_source_output1 (PV_OBJECT (object))) ||
PV_IS_SOURCE_OUTPUT1_PROXY (interface))
g_signal_emit (subscribe, signals[SIGNAL_SUBSCRIPTION_EVENT], 0, event,
PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT, g_dbus_object_get_object_path (object));
PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT, object);
}
}
@ -359,7 +359,7 @@ pv_subscribe_class_init (PvSubscribeClass * klass)
3,
PV_TYPE_SUBSCRIPTION_EVENT,
PV_TYPE_SUBSCRIPTION_FLAGS,
G_TYPE_STRING);
G_TYPE_DBUS_OBJECT_PROXY);
}
static void

View File

@ -41,10 +41,10 @@ typedef enum {
PV_SUBSCRIPTION_FLAGS_CLIENT = (1 << 0),
PV_SUBSCRIPTION_FLAGS_SOURCE = (1 << 1),
PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT = (1 << 2),
PV_SUBSCRIPTION_FLAGS_ALL = 0xf
} PvSubscriptionFlags;
#define PV_SUBSCRIPTION_FLAGS_ALL 0x3
typedef enum {
PV_SUBSCRIPTION_EVENT_NEW = 0,
PV_SUBSCRIPTION_EVENT_CHANGE = 1,

View File

@ -35,14 +35,16 @@
<method name='GetClients'>
<arg type='ao' name='clients' direction='out'/>
</method>
<method name='GetProviders'>
<arg type='ao' name='providers' direction='out'/>
</method>
<method name='GetSources'>
<arg type='ao' name='sources' direction='out'/>
</method>
</interface>
<interface name='org.pulsevideo.SourceProvider1'>
<property name='Name' type='s' access='read' />
<property name='Path' type='o' access='read' />
</interface>
<interface name='org.pulsevideo.Source1'>
<property name='Name' type='s' access='read' />
<property name='Suspended' type='b' access='read' />
@ -52,7 +54,6 @@
<arg type='aa{sv}' name='caps' direction='out'/>
</method>
<method name='CreateSourceOutput'>
<arg type='o' name='source' direction='in'/>
<arg type='a{sv}' name='props' direction='in'/>
<arg type='o' name='output' direction='out'/>
</method>

View File

@ -40,7 +40,7 @@ setup_pipeline (PvV4l2Source *source)
{
PvV4l2SourcePrivate *priv = source->priv;
priv->pipeline = gst_parse_launch ("v4l2src ! video/x-raw,width=320,height=240,framerate=30/1 ! "
priv->pipeline = gst_parse_launch ("v4l2src ! video/x-raw,width=640,height=480,framerate=30/1 ! "
"pvfdpay ! multisocketsink buffers-max=2 buffers-soft-max=1 "
"recover-policy=latest sync-method=latest name=sink sync=true "
"enable-last-sample=false", NULL);

View File

@ -32,7 +32,7 @@ struct _PvClientPrivate
PvDaemon *daemon;
gchar *object_path;
PvSource *source;
PvClient1 *client1;
GHashTable *source_outputs;
};
@ -97,6 +97,46 @@ pv_client_set_property (GObject *_object,
}
}
typedef struct {
PvClient *client;
GDBusMethodInvocation *invocation;
} CreateData;
static void
on_source_output_created (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
CreateData *data = user_data;
PvClient *client = data->client;
PvClientPrivate *priv = client->priv;
PvSource1 *source1 = PV_SOURCE1 (source_object);
GDBusMethodInvocation *invocation = data->invocation;
GError *error = NULL;
gchar *object_path, *name;
if (!pv_source1_call_create_source_output_finish (source1, &object_path, res, &error))
goto create_failed;
name = g_object_get_data (G_OBJECT (source1), "org.pulsevideo.name");
pv_client1_complete_create_source_output (priv->client1, invocation, name, object_path);
g_free (name);
g_free (data);
return;
/* ERRORS */
create_failed:
{
g_print ("failed to get connect capture: %s", error->message);
g_clear_error (&error);
g_free (data);
return;
}
}
static gboolean
handle_create_source_output (PvClient1 *interface,
GDBusMethodInvocation *invocation,
@ -107,18 +147,30 @@ handle_create_source_output (PvClient1 *interface,
PvClient *client = user_data;
PvClientPrivate *priv = client->priv;
PvDaemon *daemon = priv->daemon;
PvSource *source;
PvSourceOutput *output;
const gchar *object_path;
PvSource1 *source1;
GVariantBuilder builder;
CreateData *data;
source = pv_daemon_get_source (daemon, arg_source);
source1 = pv_daemon_get_source (daemon, arg_source);
if (source1 == NULL) {
g_dbus_method_invocation_return_dbus_error (invocation,
"org.pulsevideo.NotFound",
"No source found");
return TRUE;
}
output = pv_source_create_source_output (source, NULL, priv->object_path);
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string ("hello"));
object_path = pv_source_output_get_object_path (output);
g_hash_table_insert (priv->source_outputs, g_strdup (object_path), output);
data = g_new0 (CreateData, 1);
data->client = client;
data->invocation = invocation;
pv_client1_complete_create_source_output (interface, invocation, PV_DBUS_SERVICE, object_path);
pv_source1_call_create_source_output (source1,
g_variant_builder_end (&builder),
NULL,
on_source_output_created,
data);
return TRUE;
}
@ -135,15 +187,10 @@ client_register_object (PvClient *client, const gchar *prefix)
skel = g_dbus_object_skeleton_new (name);
g_free (name);
{
PvClient1 *iface;
iface = pv_client1_skeleton_new ();
pv_client1_set_name (iface, "poppy");
g_signal_connect (iface, "handle-create-source-output", (GCallback) handle_create_source_output, client);
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
g_object_unref (iface);
}
priv->client1 = pv_client1_skeleton_new ();
pv_client1_set_name (priv->client1, "poppy");
g_signal_connect (priv->client1, "handle-create-source-output", (GCallback) handle_create_source_output, client);
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (priv->client1));
g_free (priv->object_path);
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
@ -156,7 +203,7 @@ client_unregister_object (PvClient *client)
PvDaemon *daemon = priv->daemon;
g_hash_table_unref (priv->source_outputs);
g_clear_object (&priv->source);
g_clear_object (&priv->client1);
pv_daemon_unexport (daemon, priv->object_path);
g_free (priv->object_path);

View File

@ -23,6 +23,7 @@
#include "server/pv-daemon.h"
#include "server/pv-client.h"
#include "server/pv-source-provider.h"
#include "modules/v4l2/pv-v4l2-source.h"
#include "dbus/org-pulsevideo.h"
@ -36,7 +37,7 @@ struct _PvDaemonPrivate
GDBusObjectManagerServer *server_manager;
GHashTable *senders;
PvSource *source;
GList *sources;
};
typedef struct {
@ -46,14 +47,74 @@ typedef struct {
GHashTable *clients;
PvSubscribe *subscribe;
GHashTable *sources;
} SenderData;
static void
on_subscription_event (PvSubscribe *subscribe,
PvSubscriptionEvent event,
PvSubscriptionFlags flags,
GDBusObjectProxy *object,
gpointer user_data)
{
SenderData *data = user_data;
PvDaemon *daemon = data->daemon;
PvDaemonPrivate *priv = daemon->priv;
const gchar *object_path;
PvSource1 *source1;
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
g_print ("got event %d %d %s.%s\n", event, flags, data->sender, object_path);
if (flags != PV_SUBSCRIPTION_FLAGS_SOURCE)
return;
source1 = pv_object_peek_source1 (PV_OBJECT (object));
switch (event) {
case PV_SUBSCRIPTION_EVENT_NEW:
{
g_object_set_data (G_OBJECT (source1), "org.pulsevideo.name", data->sender);
g_hash_table_insert (data->sources, g_strdup (object_path), source1);
priv->sources = g_list_prepend (priv->sources, source1);
break;
}
case PV_SUBSCRIPTION_EVENT_CHANGE:
break;
case PV_SUBSCRIPTION_EVENT_REMOVE:
{
priv->sources = g_list_remove (priv->sources, source1);
g_hash_table_remove (data->sources, object_path);
break;
}
}
}
static void
client_name_appeared_handler (GDBusConnection *connection,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
SenderData *data = user_data;
/* subscribe to Source events. We want to be notified when this new
* sender add/change/remove sources */
data->subscribe = pv_subscribe_new ();
g_object_set (data->subscribe, "service", data->sender,
"subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE,
"connection", connection,
NULL);
g_signal_connect (data->subscribe,
"subscription-event",
(GCallback) on_subscription_event,
data);
}
static void
@ -66,22 +127,16 @@ client_name_vanished_handler (GDBusConnection *connection,
g_print ("vanished client %s\n", name);
g_hash_table_unref (data->clients);
g_hash_table_remove (priv->senders, data->sender);
g_hash_table_unref (data->clients);
g_hash_table_unref (data->sources);
g_object_unref (data->subscribe);
g_free (data->sender);
g_bus_unwatch_name (data->id);
g_free (data);
}
static void
on_subscription_event (PvSubscribe *subscribe,
PvSubscriptionEvent event,
PvSubscriptionFlags flags,
const gchar *object_path)
{
g_print ("got event %d %d %s\n", event, flags, object_path);
}
static SenderData *
sender_data_new (PvDaemon *daemon, const gchar *sender)
{
@ -92,6 +147,7 @@ sender_data_new (PvDaemon *daemon, const gchar *sender)
data->daemon = daemon;
data->sender = g_strdup (sender);
data->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
data->sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
data->id = g_bus_watch_name_on_connection (priv->connection,
sender,
@ -101,16 +157,6 @@ sender_data_new (PvDaemon *daemon, const gchar *sender)
data,
NULL);
data->subscribe = pv_subscribe_new ();
g_object_set (data->subscribe, "service", sender,
"subscription-mask", PV_SUBSCRIPTION_FLAGS_SOURCE,
"connection", priv->connection,
NULL);
g_signal_connect (data->subscribe,
"subscription-event",
(GCallback) on_subscription_event,
data);
g_hash_table_insert (priv->senders, data->sender, data);
return data;
@ -288,19 +334,21 @@ pv_daemon_unexport (PvDaemon *daemon, const gchar *object_path)
g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path);
}
PvSource *
PvSource1 *
pv_daemon_get_source (PvDaemon *daemon, const gchar *name)
{
PvDaemonPrivate *priv;
PvSource1 *source;
g_return_val_if_fail (PV_IS_DAEMON (daemon), NULL);
priv = daemon->priv;
if (priv->source == NULL) {
priv->source = pv_v4l2_source_new ();
pv_source_set_manager (priv->source, priv->server_manager);
}
return priv->source;
if (priv->sources == NULL)
return NULL;
source = priv->sources->data;
return source;
}
G_DEFINE_TYPE (PvDaemon, pv_daemon, G_TYPE_OBJECT);

View File

@ -23,6 +23,8 @@
#include <glib-object.h>
#include <gio/gio.h>
#include "dbus/org-pulsevideo.h"
G_BEGIN_DECLS
#define PV_TYPE_DAEMON (pv_daemon_get_type ())
@ -38,7 +40,8 @@ typedef struct _PvDaemon PvDaemon;
typedef struct _PvDaemonClass PvDaemonClass;
typedef struct _PvDaemonPrivate PvDaemonPrivate;
#include "client/pv-source.h"
#include <client/pv-source.h>
#include <server/pv-source-provider.h>
/**
* PvDaemon:
@ -61,17 +64,17 @@ struct _PvDaemonClass {
};
/* normal GObject stuff */
GType pv_daemon_get_type (void);
GType pv_daemon_get_type (void);
PvDaemon * pv_daemon_new (void);
PvDaemon * pv_daemon_new (void);
void pv_daemon_start (PvDaemon *daemon);
void pv_daemon_stop (PvDaemon *daemon);
void pv_daemon_start (PvDaemon *daemon);
void pv_daemon_stop (PvDaemon *daemon);
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
PvSource * pv_daemon_get_source (PvDaemon *daemon, const gchar *name);
PvSource1 * pv_daemon_get_source (PvDaemon *daemon, const gchar *name);
G_END_DECLS

View File

@ -0,0 +1,261 @@
/* Pulsevideo
* Copyright (C) 2015 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "server/pv-source-provider.h"
#include "dbus/org-pulsevideo.h"
struct _PvSourceProviderPrivate
{
PvDaemon *daemon;
gchar *object_path;
gchar *name;
gchar *path;
};
#define PV_SOURCE_PROVIDER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderPrivate))
G_DEFINE_TYPE (PvSourceProvider, pv_source_provider, G_TYPE_OBJECT);
enum
{
PROP_0,
PROP_DAEMON,
PROP_OBJECT_PATH,
PROP_NAME,
PROP_PATH,
};
static void
pv_source_provider_get_property (GObject *_object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PvSourceProvider *client = PV_SOURCE_PROVIDER (_object);
PvSourceProviderPrivate *priv = client->priv;
switch (prop_id) {
case PROP_DAEMON:
g_value_set_object (value, priv->daemon);
break;
case PROP_OBJECT_PATH:
g_value_set_string (value, priv->object_path);
break;
case PROP_NAME:
g_value_set_string (value, priv->name);
break;
case PROP_PATH:
g_value_set_string (value, priv->path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (client, prop_id, pspec);
break;
}
}
static void
pv_source_provider_set_property (GObject *_object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PvSourceProvider *client = PV_SOURCE_PROVIDER (_object);
PvSourceProviderPrivate *priv = client->priv;
switch (prop_id) {
case PROP_DAEMON:
priv->daemon = g_value_dup_object (value);
break;
case PROP_OBJECT_PATH:
priv->object_path = g_value_dup_string (value);
break;
case PROP_NAME:
priv->name = g_value_dup_string (value);
break;
case PROP_PATH:
priv->path = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (client, prop_id, pspec);
break;
}
}
static void
source_provider_register_object (PvSourceProvider *client, const gchar *prefix)
{
PvSourceProviderPrivate *priv = client->priv;
PvDaemon *daemon = priv->daemon;
GDBusObjectSkeleton *skel;
gchar *name;
name = g_strdup_printf ("%s/source", prefix);
skel = g_dbus_object_skeleton_new (name);
g_free (name);
{
PvSourceProvider1 *iface;
iface = pv_source_provider1_skeleton_new ();
g_object_set (iface, "name", priv->name, NULL);
g_object_set (iface, "path", priv->path, NULL);
g_dbus_object_skeleton_add_interface (skel, G_DBUS_INTERFACE_SKELETON (iface));
g_object_unref (iface);
}
g_free (priv->object_path);
priv->object_path = pv_daemon_export_uniquely (daemon, skel);
}
static void
source_provider_unregister_object (PvSourceProvider *client)
{
PvSourceProviderPrivate *priv = client->priv;
PvDaemon *daemon = priv->daemon;
pv_daemon_unexport (daemon, priv->object_path);
g_free (priv->object_path);
}
static void
pv_source_provider_finalize (GObject * object)
{
PvSourceProvider *client = PV_SOURCE_PROVIDER (object);
PvSourceProviderPrivate *priv = client->priv;
source_provider_unregister_object (client);
g_free (priv->name);
g_free (priv->path);
G_OBJECT_CLASS (pv_source_provider_parent_class)->finalize (object);
}
static void
pv_source_provider_constructed (GObject * object)
{
PvSourceProvider *client = PV_SOURCE_PROVIDER (object);
PvSourceProviderPrivate *priv = client->priv;
source_provider_register_object (client, priv->object_path);
G_OBJECT_CLASS (pv_source_provider_parent_class)->constructed (object);
}
static void
pv_source_provider_class_init (PvSourceProviderClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (PvSourceProviderPrivate));
gobject_class->finalize = pv_source_provider_finalize;
gobject_class->set_property = pv_source_provider_set_property;
gobject_class->get_property = pv_source_provider_get_property;
gobject_class->constructed = pv_source_provider_constructed;
g_object_class_install_property (gobject_class,
PROP_DAEMON,
g_param_spec_object ("daemon",
"Daemon",
"The daemon",
PV_TYPE_DAEMON,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_OBJECT_PATH,
g_param_spec_string ("object-path",
"Object Path",
"The object path",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"The name of the owner",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_PATH,
g_param_spec_string ("path",
"Path",
"The path",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
}
static void
pv_source_provider_init (PvSourceProvider * client)
{
client->priv = PV_SOURCE_PROVIDER_GET_PRIVATE (client);
}
/**
* pv_source_provider_new:
*
* Make a new unconnected #PvSourceProvider
*
* Returns: a new #PvSourceProvider
*/
PvSourceProvider *
pv_source_provider_new (PvDaemon *daemon,
const gchar *prefix,
const gchar *name,
const gchar *path)
{
g_return_val_if_fail (PV_IS_DAEMON (daemon), NULL);
g_return_val_if_fail (g_variant_is_object_path (prefix), NULL);
return g_object_new (PV_TYPE_SOURCE_PROVIDER, "daemon", daemon, "object-path", prefix,
"name", name, "path", path, NULL);
}
const gchar *
pv_source_provider_get_object_path (PvSourceProvider *client)
{
PvSourceProviderPrivate *priv;
g_return_val_if_fail (PV_IS_SOURCE_PROVIDER (client), NULL);
priv = client->priv;
return priv->object_path;
}

View File

@ -0,0 +1,74 @@
/* Pulsevideo
* 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 __PV_SOURCE_PROVIDER_H__
#define __PV_SOURCE_PROVIDER_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define PV_TYPE_SOURCE_PROVIDER (pv_source_provider_get_type ())
#define PV_IS_SOURCE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PV_TYPE_SOURCE_PROVIDER))
#define PV_IS_SOURCE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PV_TYPE_SOURCE_PROVIDER))
#define PV_SOURCE_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderClass))
#define PV_SOURCE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PV_TYPE_SOURCE_PROVIDER, PvSourceProvider))
#define PV_SOURCE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PV_TYPE_SOURCE_PROVIDER, PvSourceProviderClass))
#define PV_SOURCE_PROVIDER_CAST(obj) ((PvSourceProvider*)(obj))
#define PV_SOURCE_PROVIDER_CLASS_CAST(klass) ((PvSourceProviderClass*)(klass))
typedef struct _PvSourceProvider PvSourceProvider;
typedef struct _PvSourceProviderClass PvSourceProviderClass;
typedef struct _PvSourceProviderPrivate PvSourceProviderPrivate;
#include "pv-daemon.h"
/**
* PvSourceProvider:
*
* Pulsevideo source provider object class.
*/
struct _PvSourceProvider {
GObject object;
PvSourceProviderPrivate *priv;
};
/**
* PvSourceProviderClass:
*
* Pulsevideo source provider object class.
*/
struct _PvSourceProviderClass {
GObjectClass parent_class;
};
/* normal GObject stuff */
GType pv_source_provider_get_type (void);
PvSourceProvider * pv_source_provider_new (PvDaemon *daemon, const gchar *prefix,
const gchar *name, const gchar *path);
const gchar * pv_source_provider_get_object_path (PvSourceProvider *client);
G_END_DECLS
#endif /* __PV_SOURCE_PROVIDER_H__ */

View File

@ -22,7 +22,7 @@
#include <client/pulsevideo.h>
#define CAPS "video/x-raw, format=(string)YUY2, width=(int)320, height=(int)240, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1"
#define CAPS "video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)30/1"
static GMainLoop *loop;

View File

@ -25,9 +25,9 @@ static GMainLoop *loop;
static void
subscription_cb (PvContext *context, PvSubscriptionEvent type, PvSubscriptionFlags flags,
const gchar *object_path, gpointer user_data)
GDBusObject *object, gpointer user_data)
{
g_print ("got event %d %d %s\n", type, flags, object_path);
g_print ("got event %d %d %s\n", type, flags, g_dbus_object_get_object_path (object));
}
static void