Make source and source-output server side only

Move source and source-output to the server side again.
Make the daemon track objects per sender so that we can remove them
when the sender disappears.
This commit is contained in:
Wim Taymans 2015-05-05 18:20:32 +02:00
parent 1b89f2f8ad
commit d9444ab360
17 changed files with 139 additions and 205 deletions

View file

@ -61,7 +61,6 @@ dbuspolicy_DATA = \
enumtypesincludes = client/pv-context.h \
client/pv-introspect.h \
client/pv-source.h \
client/pv-stream.h \
client/pv-subscribe.h
@ -163,8 +162,6 @@ pulsevideoinclude_HEADERS = \
client/pv-introspect.h \
client/pv-stream.h \
client/pv-subscribe.h \
client/pv-source.h \
client/pv-source-output.h \
dbus/org-pulsevideo.h
lib_LTLIBRARIES = \
@ -177,8 +174,6 @@ libpulsevideo_@PV_MAJORMINOR@_la_SOURCES = \
client/pv-introspect.h client/pv-introspect.c \
client/pv-stream.h client/pv-stream.c \
client/pulsevideo.c client/pulsevideo.h \
client/pv-source-output.c client/pv-source-output.h \
client/pv-source.c client/pv-source.h \
client/pv-subscribe.c client/pv-subscribe.h \
dbus/org-pulsevideo.c \
$(pulsevideogstsource)
@ -198,6 +193,8 @@ lib_LTLIBRARIES += libpulsevideocore-@PV_MAJORMINOR@.la
libpulsevideocore_@PV_MAJORMINOR@_la_SOURCES = \
server/pv-client.c server/pv-client.h \
server/pv-daemon.c server/pv-daemon.h \
server/pv-source.c server/pv-source.h \
server/pv-source-output.c server/pv-source-output.h \
modules/v4l2/pv-v4l2-source.c
libpulsevideocore_@PV_MAJORMINOR@_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)

View file

@ -20,8 +20,6 @@
#ifndef __PULSEVIDEO_H__
#define __PULSEVIDEO_H__
#include <client/pv-source.h>
#include <client/pv-source-output.h>
#include <client/pv-stream.h>
#include <client/pv-context.h>
#include <client/pv-subscribe.h>

View file

@ -576,52 +576,6 @@ pv_context_disconnect (PvContext *context)
return TRUE;
}
/**
* pv_context_register_source:
* @context: a #PvContext
* @source: a #PvSource
*
* Register @source in @context. This makes @source availabe to other
* connected clients.
*
* Returns: %TRUE on success.
*/
gboolean
pv_context_register_source (PvContext *context, PvSource *source)
{
PvContextPrivate *priv;
g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
g_return_val_if_fail (PV_IS_SOURCE (source), FALSE);
priv = context->priv;
pv_source_set_manager (source, priv->server_manager);
return TRUE;
}
/**
* pv_context_unregister_source:
* @context: a #PvContext
* @source: a #PvSource
*
* Unregister @source from @context. @source will no longer be
* available for clients.
*
* Returns: %TRUE on success.
*/
gboolean
pv_context_unregister_source (PvContext *context, PvSource *source)
{
g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
g_return_val_if_fail (PV_IS_SOURCE (source), FALSE);
pv_source_set_manager (source, NULL);
return TRUE;
}
/**
* pv_context_get_state:
* @context: a #PvContext

View file

@ -23,7 +23,6 @@
#include <glib-object.h>
#include <gio/gio.h>
#include <client/pv-source.h>
#include <client/pv-subscribe.h>
G_BEGIN_DECLS
@ -105,9 +104,6 @@ PvContext * pv_context_new (GMainContext *ctx,
gboolean pv_context_connect (PvContext *context, PvContextFlags flags);
gboolean pv_context_disconnect (PvContext *context);
gboolean pv_context_register_source (PvContext *context, PvSource *source);
gboolean pv_context_unregister_source (PvContext *context, PvSource *source);
PvContextState pv_context_get_state (PvContext *context);
const GError * pv_context_get_error (PvContext *context);

View file

@ -27,6 +27,27 @@
G_BEGIN_DECLS
/**
* PvSourceState:
* @PV_SOURCE_STATE_ERROR: the source is in error
* @PV_SOURCE_STATE_SUSPENDED: the source is suspended, the device might
* be closed
* @PV_SOURCE_STATE_INIT: the source is initializing, it opens the device
* and gets the device capabilities
* @PV_SOURCE_STATE_IDLE: the source is running but there is no active
* source-output
* @PV_SOURCE_STATE_RUNNING: the source is running.
*
* The different source states
*/
typedef enum {
PV_SOURCE_STATE_ERROR = 0,
PV_SOURCE_STATE_SUSPENDED = 1,
PV_SOURCE_STATE_INIT = 2,
PV_SOURCE_STATE_IDLE = 3,
PV_SOURCE_STATE_RUNNING = 4,
} PvSourceState;
/**
* PvSourceInfo:
* @name: the name of the source

View file

@ -191,6 +191,14 @@ add_interface (PvSubscribe *subscribe,
data);
}
static void
remove_interface (PvSubscribe *subscribe,
const gchar *object_path,
const gchar *interface_name)
{
g_print ("remove interface %s\n", interface_name);
}
static void
add_ifaces_and_properties (PvSubscribe *subscribe,
const gchar *object_path,
@ -212,6 +220,18 @@ add_ifaces_and_properties (PvSubscribe *subscribe,
}
}
static void
remove_ifaces (PvSubscribe *subscribe,
const gchar *object_path,
const gchar **ifaces)
{
while (*ifaces) {
remove_interface (subscribe, object_path, *ifaces);
ifaces++;
}
}
static void
on_manager_proxy_signal (GDBusProxy *proxy,
const gchar *sender_name,
@ -242,6 +262,7 @@ on_manager_proxy_signal (GDBusProxy *proxy,
&object_path,
&ifaces);
remove_ifaces (subscribe, object_path, ifaces);
g_free (ifaces);
}

View file

@ -29,7 +29,6 @@ main (gint argc, gchar *argv[])
{
PvDaemon *daemon;
GMainLoop *loop;
PvSource *source;
pv_init (&argc, &argv);
@ -37,8 +36,7 @@ main (gint argc, gchar *argv[])
daemon = pv_daemon_new ();
source = pv_v4l2_source_new();
pv_daemon_add_source (daemon, source);
pv_v4l2_source_new (daemon);
pv_daemon_start (daemon);
g_main_loop_run (loop);

View file

@ -257,7 +257,7 @@ pv_v4l2_source_init (PvV4l2Source * source)
}
PvSource *
pv_v4l2_source_new (void)
pv_v4l2_source_new (PvDaemon *daemon)
{
return g_object_new (PV_TYPE_V4L2_SOURCE, "name", "v4l2", NULL);
return g_object_new (PV_TYPE_V4L2_SOURCE, "daemon", daemon, "name", "v4l2", NULL);
}

View file

@ -23,6 +23,8 @@
#include <glib-object.h>
#include <client/pulsevideo.h>
#include <server/pv-daemon.h>
#include <server/pv-source.h>
G_BEGIN_DECLS
@ -51,7 +53,7 @@ struct _PvV4l2SourceClass {
GType pv_v4l2_source_get_type (void);
PvSource * pv_v4l2_source_new (void);
PvSource * pv_v4l2_source_new (PvDaemon *daemon);
G_END_DECLS

View file

@ -20,8 +20,6 @@
#include "client/pulsevideo.h"
#include "client/pv-enumtypes.h"
#include "client/pv-source.h"
#include "client/pv-source-output.h"
#include "server/pv-client.h"
@ -34,8 +32,6 @@ struct _PvClientPrivate
gchar *object_path;
PvClient1 *client1;
GHashTable *source_outputs;
};
#define PV_CLIENT_GET_PRIVATE(obj) \
@ -133,7 +129,6 @@ client_unregister_object (PvClient *client)
PvClientPrivate *priv = client->priv;
PvDaemon *daemon = priv->daemon;
g_hash_table_unref (priv->source_outputs);
g_clear_object (&priv->client1);
pv_daemon_unexport (daemon, priv->object_path);
@ -207,9 +202,7 @@ pv_client_class_init (PvClientClass * klass)
static void
pv_client_init (PvClient * client)
{
PvClientPrivate *priv = client->priv = PV_CLIENT_GET_PRIVATE (client);
priv->source_outputs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
client->priv = PV_CLIENT_GET_PRIVATE (client);
}

View file

@ -45,7 +45,7 @@ typedef struct {
guint id;
gchar *sender;
PvDaemon *daemon;
GList *clients;
GList *objects;
} SenderData;
static void
@ -109,7 +109,7 @@ data_free (SenderData *data)
{
g_print ("free client %s %p\n", data->sender, data);
g_list_free_full (data->clients, g_object_unref);
g_list_free_full (data->objects, g_object_unref);
g_hash_table_remove (data->daemon->priv->senders, data->sender);
g_free (data->sender);
g_free (data);
@ -148,24 +148,19 @@ handle_connect_client (PvDaemon1 *interface,
gpointer user_data)
{
PvDaemon *daemon = user_data;
PvDaemonPrivate *priv = daemon->priv;
PvClient *client;
const gchar *sender, *object_path;
SenderData *data;
sender = g_dbus_method_invocation_get_sender (invocation);
g_print ("connect client %s\n", sender);
data = g_hash_table_lookup (priv->senders, sender);
if (data == NULL)
data = sender_data_new (daemon, sender);
client = pv_client_new (daemon, sender, PV_DBUS_OBJECT_PREFIX);
pv_daemon_track_object (daemon, sender, G_OBJECT (client));
object_path = pv_client_get_object_path (client);
data->clients = g_list_prepend (data->clients, client);
pv_daemon1_complete_connect_client (interface, invocation, object_path);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", object_path));
return TRUE;
}
@ -331,39 +326,25 @@ pv_daemon_unexport (PvDaemon *daemon, const gchar *object_path)
g_dbus_object_manager_server_unexport (daemon->priv->server_manager, object_path);
}
/**
* pv_daemon_add_source:
* @daemon: a #PvDaemon
* @source: a #PvSource
*
* Register @source with @daemon so that it becomes available to clients.
*/
void
pv_daemon_add_source (PvDaemon *daemon, PvSource *source)
pv_daemon_track_object (PvDaemon *daemon,
const gchar *sender,
GObject *object)
{
PvDaemonPrivate *priv;
SenderData *data;
g_return_if_fail (PV_IS_DAEMON (daemon));
g_return_if_fail (PV_IS_SOURCE (source));
g_return_if_fail (sender != NULL);
g_return_if_fail (G_IS_OBJECT (object));
priv = daemon->priv;
pv_source_set_manager (source, priv->server_manager);
}
data = g_hash_table_lookup (priv->senders, sender);
if (data == NULL)
data = sender_data_new (daemon, sender);
/**
* pv_daemon_remove_source:
* @daemon: a #PvDaemon
* @source: a #PvSource
*
* Unregister @source from @daemon so that it becomes unavailable to clients.
*/
void
pv_daemon_remove_source (PvDaemon *daemon, PvSource *source)
{
g_return_if_fail (PV_IS_DAEMON (daemon));
g_return_if_fail (PV_IS_SOURCE (source));
pv_source_set_manager (source, NULL);
data->objects = g_list_prepend (data->objects, object);
}
G_DEFINE_TYPE (PvDaemon, pv_daemon, G_TYPE_OBJECT);

View file

@ -38,7 +38,7 @@ typedef struct _PvDaemon PvDaemon;
typedef struct _PvDaemonClass PvDaemonClass;
typedef struct _PvDaemonPrivate PvDaemonPrivate;
#include <client/pv-source.h>
#include <server/pv-source.h>
/**
* PvDaemon:
@ -71,8 +71,7 @@ void pv_daemon_stop (PvDaemon *daemon);
gchar * pv_daemon_export_uniquely (PvDaemon *daemon, GDBusObjectSkeleton *skel);
void pv_daemon_unexport (PvDaemon *daemon, const gchar *name);
void pv_daemon_add_source (PvDaemon *daemon, PvSource *source);
void pv_daemon_remove_source (PvDaemon *daemon, PvSource *source);
void pv_daemon_track_object (PvDaemon *daemon, const gchar *sender, GObject *object);
G_END_DECLS

View file

@ -21,14 +21,16 @@
#include <gio/gunixfdlist.h>
#include "client/pv-source-output.h"
#include "client/pv-enumtypes.h"
#include "server/pv-daemon.h"
#include "server/pv-source-output.h"
#include "dbus/org-pulsevideo.h"
struct _PvSourceOutputPrivate
{
GDBusObjectManagerServer *server_manager;
PvDaemon *daemon;
gchar *object_path;
gchar *source;
@ -44,7 +46,7 @@ G_DEFINE_TYPE (PvSourceOutput, pv_source_output, G_TYPE_OBJECT);
enum
{
PROP_0,
PROP_MANAGER,
PROP_DAEMON,
PROP_OBJECT_PATH,
PROP_SOURCE,
PROP_SOCKET,
@ -60,8 +62,8 @@ pv_source_output_get_property (GObject *_object,
PvSourceOutputPrivate *priv = output->priv;
switch (prop_id) {
case PROP_MANAGER:
g_value_set_object (value, priv->server_manager);
case PROP_DAEMON:
g_value_set_object (value, priv->daemon);
break;
case PROP_OBJECT_PATH:
@ -92,8 +94,8 @@ pv_source_output_set_property (GObject *_object,
PvSourceOutputPrivate *priv = output->priv;
switch (prop_id) {
case PROP_MANAGER:
priv->server_manager = g_value_dup_object (value);
case PROP_DAEMON:
priv->daemon = g_value_dup_object (value);
break;
case PROP_OBJECT_PATH:
@ -161,7 +163,7 @@ handle_stop (PvSourceOutput1 *interface,
stop_transfer (output);
pv_source_output1_complete_stop (interface, invocation);
g_dbus_method_invocation_return_value (invocation, NULL);
return TRUE;
}
@ -175,7 +177,7 @@ handle_remove (PvSourceOutput1 *interface,
stop_transfer (output);
pv_source_output1_complete_remove (interface, invocation);
g_dbus_method_invocation_return_value (invocation, NULL);
return TRUE;
}
@ -202,10 +204,9 @@ output_register_object (PvSourceOutput *output, const gchar *prefix)
pv_object_skeleton_set_source_output1 (skel, iface);
g_object_unref (iface);
}
g_dbus_object_manager_server_export_uniquely (priv->server_manager, G_DBUS_OBJECT_SKELETON (skel));
g_free (priv->object_path);
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
priv->object_path = pv_daemon_export_uniquely (priv->daemon, G_DBUS_OBJECT_SKELETON (skel));
}
static void
@ -215,7 +216,7 @@ output_unregister_object (PvSourceOutput *output)
stop_transfer (output);
g_dbus_object_manager_server_unexport (priv->server_manager, priv->object_path);
pv_daemon_unexport (priv->daemon, priv->object_path);
}
static void
@ -226,7 +227,7 @@ pv_source_output_finalize (GObject * object)
output_unregister_object (output);
g_object_unref (priv->server_manager);
g_object_unref (priv->daemon);
g_free (priv->object_path);
g_free (priv->source);
@ -257,11 +258,11 @@ pv_source_output_class_init (PvSourceOutputClass * klass)
gobject_class->constructed = pv_source_output_constructed;
g_object_class_install_property (gobject_class,
PROP_MANAGER,
g_param_spec_object ("manager",
"Manager",
"The manager",
G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
PROP_DAEMON,
g_param_spec_object ("daemon",
"Daemon",
"The Daemon",
PV_TYPE_DAEMON,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));

View file

@ -20,9 +20,11 @@
#include <gio/gio.h>
#include "client/pulsevideo.h"
#include "client/pv-source.h"
#include "client/pv-enumtypes.h"
#include "server/pv-source.h"
#include "server/pv-daemon.h"
#include "dbus/org-pulsevideo.h"
@ -31,7 +33,7 @@
struct _PvSourcePrivate
{
GDBusObjectManagerServer *server_manager;
PvDaemon *daemon;
PvSource1 *iface;
gchar *object_path;
@ -47,7 +49,7 @@ G_DEFINE_ABSTRACT_TYPE (PvSource, pv_source, G_TYPE_OBJECT);
enum
{
PROP_0,
PROP_MANAGER,
PROP_DAEMON,
PROP_OBJECT_PATH,
PROP_NAME,
PROP_STATE,
@ -64,8 +66,8 @@ pv_source_get_property (GObject *_object,
PvSourcePrivate *priv = source->priv;
switch (prop_id) {
case PROP_MANAGER:
g_value_set_object (value, priv->server_manager);
case PROP_DAEMON:
g_value_set_object (value, priv->daemon);
break;
case PROP_OBJECT_PATH:
@ -100,8 +102,8 @@ pv_source_set_property (GObject *_object,
PvSourcePrivate *priv = source->priv;
switch (prop_id) {
case PROP_MANAGER:
pv_source_set_manager (source, g_value_dup_object (value));
case PROP_DAEMON:
priv->daemon = g_value_dup_object (value);
break;
case PROP_OBJECT_PATH:
@ -135,17 +137,20 @@ handle_create_source_output (PvSource1 *interface,
PvSource *source = user_data;
PvSourcePrivate *priv = source->priv;
PvSourceOutput *output;
const gchar *object_path;
const gchar *object_path, *sender;
output = pv_source_create_source_output (source, arg_properties, priv->object_path);
if (output == NULL)
goto no_output;
object_path = pv_source_output_get_object_path (output);
sender = g_dbus_method_invocation_get_sender (invocation);
pv_daemon_track_object (priv->daemon, sender, G_OBJECT (output));
object_path = pv_source_output_get_object_path (output);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", object_path));
pv_source1_complete_create_source_output (interface,
invocation,
object_path);
return TRUE;
/* ERRORS */
@ -168,9 +173,9 @@ handle_get_capabilities (PvSource1 *interface,
out_caps = pv_source_get_capabilities (source, arg_properties);
pv_source1_complete_get_capabilities (interface,
invocation,
out_caps);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(@aa{sv})", out_caps));
return TRUE;
}
@ -179,6 +184,7 @@ static void
source_register_object (PvSource *source)
{
PvSourcePrivate *priv = source->priv;
PvDaemon *daemon = priv->daemon;
PvObjectSkeleton *skel;
skel = pv_object_skeleton_new (PV_DBUS_OBJECT_SOURCE);
@ -196,11 +202,8 @@ source_register_object (PvSource *source)
source);
pv_object_skeleton_set_source1 (skel, priv->iface);
g_dbus_object_manager_server_export_uniquely (priv->server_manager, G_DBUS_OBJECT_SKELETON (skel));
g_object_unref (skel);
g_free (priv->object_path);
priv->object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (skel)));
priv->object_path = pv_daemon_export_uniquely (daemon, G_DBUS_OBJECT_SKELETON (skel));
return;
}
@ -210,20 +213,28 @@ source_unregister_object (PvSource *source)
{
PvSourcePrivate *priv = source->priv;
g_dbus_object_manager_server_unexport (priv->server_manager, priv->object_path);
pv_daemon_unexport (priv->daemon, priv->object_path);
g_clear_object (&priv->iface);
}
static void
pv_source_constructed (GObject * object)
{
PvSource *source = PV_SOURCE (object);
source_register_object (source);
G_OBJECT_CLASS (pv_source_parent_class)->constructed (object);
}
static void
pv_source_finalize (GObject * object)
{
PvSource *source = PV_SOURCE (object);
PvSourcePrivate *priv = source->priv;
if (priv->server_manager) {
source_unregister_object (source);
g_object_unref (priv->server_manager);
}
source_unregister_object (source);
g_free (priv->object_path);
g_free (priv->name);
g_variant_unref (priv->properties);
@ -236,7 +247,7 @@ default_create_source_output (PvSource *source, GVariant *props, const gchar *pr
{
PvSourcePrivate *priv = source->priv;
return g_object_new (PV_TYPE_SOURCE_OUTPUT, "manager", priv->server_manager,
return g_object_new (PV_TYPE_SOURCE_OUTPUT, "daemon", priv->daemon,
"object-path", prefix,
"source", priv->object_path, NULL);
}
@ -257,16 +268,18 @@ pv_source_class_init (PvSourceClass * klass)
g_type_class_add_private (klass, sizeof (PvSourcePrivate));
gobject_class->finalize = pv_source_finalize;
gobject_class->constructed = pv_source_constructed;
gobject_class->set_property = pv_source_set_property;
gobject_class->get_property = pv_source_get_property;
g_object_class_install_property (gobject_class,
PROP_MANAGER,
g_param_spec_object ("manager",
"Manager",
"The manager",
G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
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,
@ -319,25 +332,6 @@ pv_source_init (PvSource * source)
source->priv = PV_SOURCE_GET_PRIVATE (source);
}
void
pv_source_set_manager (PvSource *source, GDBusObjectManagerServer *manager)
{
PvSourcePrivate *priv;
g_return_if_fail (PV_IS_SOURCE (source));
priv = source->priv;
if (priv->server_manager) {
source_unregister_object (source);
g_object_unref (priv->server_manager);
}
priv->server_manager = manager;
if (priv->server_manager) {
source_register_object (source);
}
}
GVariant *
pv_source_get_capabilities (PvSource *source, GVariant *props)
{

View file

@ -29,7 +29,8 @@ typedef struct _PvSource PvSource;
typedef struct _PvSourceClass PvSourceClass;
typedef struct _PvSourcePrivate PvSourcePrivate;
#include "client/pv-source-output.h"
#include "client/pv-introspect.h"
#include "server/pv-source-output.h"
#define PV_TYPE_SOURCE (pv_source_get_type ())
#define PV_IS_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PV_TYPE_SOURCE))
@ -40,26 +41,6 @@ typedef struct _PvSourcePrivate PvSourcePrivate;
#define PV_SOURCE_CAST(obj) ((PvSource*)(obj))
#define PV_SOURCE_CLASS_CAST(klass) ((PvSourceClass*)(klass))
/**
* PvSourceState:
* @PV_SOURCE_STATE_ERROR: the source is in error
* @PV_SOURCE_STATE_SUSPENDED: the source is suspended, the device might
* be closed
* @PV_SOURCE_STATE_INIT: the source is initializing, it opens the device
* and gets the device capabilities
* @PV_SOURCE_STATE_IDLE: the source is running but there is no active
* source-output
* @PV_SOURCE_STATE_RUNNING: the source is running.
*
* The different source states
*/
typedef enum {
PV_SOURCE_STATE_ERROR = 0,
PV_SOURCE_STATE_SUSPENDED = 1,
PV_SOURCE_STATE_INIT = 2,
PV_SOURCE_STATE_IDLE = 3,
PV_SOURCE_STATE_RUNNING = 4,
} PvSourceState;
/**
* PvSource:
*
@ -94,8 +75,6 @@ struct _PvSourceClass {
/* normal GObject stuff */
GType pv_source_get_type (void);
void pv_source_set_manager (PvSource *source, GDBusObjectManagerServer *manager);
GVariant * pv_source_get_capabilities (PvSource *source, GVariant *props);
gboolean pv_source_set_state (PvSource *source, PvSourceState state);

View file

@ -32,7 +32,7 @@ on_state_notify (GObject *gobject,
gpointer user_data)
{
PvContextState state;
PvContext *c = user_data;
//PvContext *c = user_data;
g_object_get (gobject, "state", &state, NULL);
g_print ("got context state %d\n", state);
@ -43,10 +43,10 @@ on_state_notify (GObject *gobject,
break;
case PV_CONTEXT_STATE_READY:
{
PvSource *source;
//PvSource *source;
source = pv_v4l2_source_new ();
pv_context_register_source (c, source);
//source = pv_v4l2_source_new (NULL);
//pv_context_register_source (c, source);
break;
}
default: