mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
misc hacking
Add introspect API Move private things to private.h Use custom main-context for the context, and ensure everything is called from the custom main-context. does not work well with glib proxy signals yet. Work with custom mainloop in the gstreamer element.
This commit is contained in:
parent
592e99a317
commit
c185755b3f
16 changed files with 489 additions and 157 deletions
|
|
@ -60,6 +60,7 @@ dbuspolicy_DATA = \
|
||||||
###################################
|
###################################
|
||||||
|
|
||||||
enumtypesincludes = client/pv-context.h \
|
enumtypesincludes = client/pv-context.h \
|
||||||
|
client/pv-introspect.h \
|
||||||
client/pv-source.h \
|
client/pv-source.h \
|
||||||
client/pv-stream.h \
|
client/pv-stream.h \
|
||||||
client/pv-subscribe.h
|
client/pv-subscribe.h
|
||||||
|
|
@ -159,6 +160,7 @@ pulsevideoinclude_HEADERS = \
|
||||||
client/pulsevideo.h \
|
client/pulsevideo.h \
|
||||||
client/pv-context.h \
|
client/pv-context.h \
|
||||||
client/pv-enumtypes.h \
|
client/pv-enumtypes.h \
|
||||||
|
client/pv-introspect.h \
|
||||||
client/pv-stream.h \
|
client/pv-stream.h \
|
||||||
client/pv-subscribe.h \
|
client/pv-subscribe.h \
|
||||||
client/pv-source.h \
|
client/pv-source.h \
|
||||||
|
|
@ -172,6 +174,7 @@ lib_LTLIBRARIES = \
|
||||||
libpulsevideo_@PV_MAJORMINOR@_la_SOURCES = \
|
libpulsevideo_@PV_MAJORMINOR@_la_SOURCES = \
|
||||||
client/pv-context.h client/pv-context.c \
|
client/pv-context.h client/pv-context.c \
|
||||||
client/pv-enumtypes.h client/pv-enumtypes.c \
|
client/pv-enumtypes.h client/pv-enumtypes.c \
|
||||||
|
client/pv-introspect.h client/pv-introspect.c \
|
||||||
client/pv-stream.h client/pv-stream.c \
|
client/pv-stream.h client/pv-stream.c \
|
||||||
client/pulsevideo.c client/pulsevideo.h \
|
client/pulsevideo.c client/pulsevideo.h \
|
||||||
client/pv-source-output.c client/pv-source-output.h \
|
client/pv-source-output.c client/pv-source-output.h \
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include <client/pv-stream.h>
|
#include <client/pv-stream.h>
|
||||||
#include <client/pv-context.h>
|
#include <client/pv-context.h>
|
||||||
#include <client/pv-subscribe.h>
|
#include <client/pv-subscribe.h>
|
||||||
|
#include <client/pv-introspect.h>
|
||||||
|
|
||||||
#define PV_DBUS_SERVICE "org.pulsevideo"
|
#define PV_DBUS_SERVICE "org.pulsevideo"
|
||||||
#define PV_DBUS_OBJECT_PREFIX "/org/pulsevideo"
|
#define PV_DBUS_OBJECT_PREFIX "/org/pulsevideo"
|
||||||
|
|
|
||||||
|
|
@ -25,31 +25,7 @@
|
||||||
|
|
||||||
#include "dbus/org-pulsevideo.h"
|
#include "dbus/org-pulsevideo.h"
|
||||||
|
|
||||||
struct _PvContextPrivate
|
#include "client/pv-private.h"
|
||||||
{
|
|
||||||
gchar *name;
|
|
||||||
GVariant *properties;
|
|
||||||
|
|
||||||
guint id;
|
|
||||||
GDBusConnection *connection;
|
|
||||||
|
|
||||||
PvContextFlags flags;
|
|
||||||
PvContextState state;
|
|
||||||
|
|
||||||
PvDaemon1 *daemon;
|
|
||||||
|
|
||||||
PvClient1 *client;
|
|
||||||
|
|
||||||
PvSubscriptionFlags subscription_mask;
|
|
||||||
PvSubscribe *subscribe;
|
|
||||||
|
|
||||||
GList *sources;
|
|
||||||
|
|
||||||
GDBusObjectManagerServer *server_manager;
|
|
||||||
|
|
||||||
GError *error;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define PV_CONTEXT_GET_PRIVATE(obj) \
|
#define PV_CONTEXT_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PV_TYPE_CONTEXT, PvContextPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), PV_TYPE_CONTEXT, PvContextPrivate))
|
||||||
|
|
@ -67,6 +43,7 @@ subscription_cb (PvSubscribe *subscribe,
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
PROP_MAIN_CONTEXT,
|
||||||
PROP_NAME,
|
PROP_NAME,
|
||||||
PROP_PROPERTIES,
|
PROP_PROPERTIES,
|
||||||
PROP_STATE,
|
PROP_STATE,
|
||||||
|
|
@ -92,6 +69,10 @@ pv_context_get_property (GObject *_object,
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_MAIN_CONTEXT:
|
||||||
|
g_value_set_pointer (value, priv->context);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_NAME:
|
case PROP_NAME:
|
||||||
g_value_set_string (value, priv->name);
|
g_value_set_string (value, priv->name);
|
||||||
break;
|
break;
|
||||||
|
|
@ -128,6 +109,10 @@ pv_context_set_property (GObject *_object,
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_MAIN_CONTEXT:
|
||||||
|
priv->context = g_value_get_pointer (value);
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_NAME:
|
case PROP_NAME:
|
||||||
g_free (priv->name);
|
g_free (priv->name);
|
||||||
priv->name = g_value_dup_string (value);
|
priv->name = g_value_dup_string (value);
|
||||||
|
|
@ -173,6 +158,19 @@ pv_context_class_init (PvContextClass * klass)
|
||||||
gobject_class->set_property = pv_context_set_property;
|
gobject_class->set_property = pv_context_set_property;
|
||||||
gobject_class->get_property = pv_context_get_property;
|
gobject_class->get_property = pv_context_get_property;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PvContext:main-context
|
||||||
|
*
|
||||||
|
* The main context to use
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_MAIN_CONTEXT,
|
||||||
|
g_param_spec_pointer ("main-context",
|
||||||
|
"Main Context",
|
||||||
|
"The main context to use",
|
||||||
|
G_PARAM_READWRITE |
|
||||||
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
|
G_PARAM_STATIC_STRINGS));
|
||||||
/**
|
/**
|
||||||
* PvContext:name
|
* PvContext:name
|
||||||
*
|
*
|
||||||
|
|
@ -288,9 +286,9 @@ pv_context_init (PvContext * context)
|
||||||
* Returns: a new unconnected #PvContext
|
* Returns: a new unconnected #PvContext
|
||||||
*/
|
*/
|
||||||
PvContext *
|
PvContext *
|
||||||
pv_context_new (const gchar *name, GVariant *properties)
|
pv_context_new (GMainContext *context, const gchar *name, GVariant *properties)
|
||||||
{
|
{
|
||||||
return g_object_new (PV_TYPE_CONTEXT, "name", name, "properties", properties, NULL);
|
return g_object_new (PV_TYPE_CONTEXT, "main-context", context, "name", name, "properties", properties, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -311,6 +309,8 @@ on_client_proxy (GObject *source_object,
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
priv->client = pv_client1_proxy_new_finish (res, &error);
|
priv->client = pv_client1_proxy_new_finish (res, &error);
|
||||||
if (priv->client == NULL) {
|
if (priv->client == NULL) {
|
||||||
priv->error = error;
|
priv->error = error;
|
||||||
|
|
@ -331,6 +331,8 @@ on_client_connected (GObject *source_object,
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gchar *client_path;
|
gchar *client_path;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
if (!pv_daemon1_call_connect_client_finish (priv->daemon, &client_path, res, &error)) {
|
if (!pv_daemon1_call_connect_client_finish (priv->daemon, &client_path, res, &error)) {
|
||||||
priv->error = error;
|
priv->error = error;
|
||||||
context_set_state (context, PV_CONTEXT_STATE_ERROR);
|
context_set_state (context, PV_CONTEXT_STATE_ERROR);
|
||||||
|
|
@ -356,6 +358,8 @@ on_daemon_connected (GObject *source_object,
|
||||||
PvContext *context = user_data;
|
PvContext *context = user_data;
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
context_set_state (context, PV_CONTEXT_STATE_REGISTERING);
|
context_set_state (context, PV_CONTEXT_STATE_REGISTERING);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -385,6 +389,9 @@ subscription_cb (PvSubscribe *subscribe,
|
||||||
|
|
||||||
g_print ("got event %d %d\n", event, flags);
|
g_print ("got event %d %d\n", event, flags);
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
|
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
case PV_SUBSCRIPTION_FLAGS_DAEMON:
|
case PV_SUBSCRIPTION_FLAGS_DAEMON:
|
||||||
priv->daemon = PV_DAEMON1 (object);
|
priv->daemon = PV_DAEMON1 (object);
|
||||||
|
|
@ -394,7 +401,10 @@ subscription_cb (PvSubscribe *subscribe,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PV_SUBSCRIPTION_FLAGS_SOURCE:
|
case PV_SUBSCRIPTION_FLAGS_SOURCE:
|
||||||
priv->sources = g_list_prepend (priv->sources, object);
|
if (event == PV_SUBSCRIPTION_EVENT_NEW)
|
||||||
|
priv->sources = g_list_prepend (priv->sources, object);
|
||||||
|
else if (event == PV_SUBSCRIPTION_EVENT_REMOVE)
|
||||||
|
priv->sources = g_list_remove (priv->sources, object);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT:
|
case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT:
|
||||||
|
|
@ -417,9 +427,13 @@ subscription_state (GObject *object,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
PvContext *context = user_data;
|
PvContext *context = user_data;
|
||||||
|
PvContextPrivate *priv = context->priv;
|
||||||
PvSubscriptionState state;
|
PvSubscriptionState state;
|
||||||
|
|
||||||
g_object_get (object, "state", &state, NULL);
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
g_assert (object == G_OBJECT (priv->subscribe));
|
||||||
|
|
||||||
|
state = pv_subscribe_get_state (priv->subscribe);
|
||||||
g_print ("got subscription state %d\n", state);
|
g_print ("got subscription state %d\n", state);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
@ -442,6 +456,10 @@ on_name_appeared (GDBusConnection *connection,
|
||||||
PvContext *context = user_data;
|
PvContext *context = user_data;
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
|
g_print ("context: on name appeared\n");
|
||||||
|
|
||||||
priv->connection = connection;
|
priv->connection = connection;
|
||||||
g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
|
g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
|
||||||
|
|
||||||
|
|
@ -457,6 +475,10 @@ on_name_vanished (GDBusConnection *connection,
|
||||||
PvContext *context = user_data;
|
PvContext *context = user_data;
|
||||||
PvContextPrivate *priv = context->priv;
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context);
|
||||||
|
|
||||||
|
g_print ("context: on name vanished\n");
|
||||||
|
|
||||||
priv->connection = connection;
|
priv->connection = connection;
|
||||||
g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
|
g_dbus_object_manager_server_set_connection (priv->server_manager, connection);
|
||||||
|
|
||||||
|
|
@ -470,6 +492,26 @@ on_name_vanished (GDBusConnection *connection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_connect (PvContext *context)
|
||||||
|
{
|
||||||
|
PvContextPrivate *priv = context->priv;
|
||||||
|
GBusNameWatcherFlags nw_flags;
|
||||||
|
|
||||||
|
nw_flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
|
||||||
|
if (!(priv->flags & PV_CONTEXT_FLAGS_NOAUTOSPAWN))
|
||||||
|
nw_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START;
|
||||||
|
|
||||||
|
priv->id = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
||||||
|
PV_DBUS_SERVICE,
|
||||||
|
nw_flags,
|
||||||
|
on_name_appeared,
|
||||||
|
on_name_vanished,
|
||||||
|
context,
|
||||||
|
NULL);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_context_connect:
|
* pv_context_connect:
|
||||||
* @context: a #PvContext
|
* @context: a #PvContext
|
||||||
|
|
@ -483,7 +525,6 @@ gboolean
|
||||||
pv_context_connect (PvContext *context, PvContextFlags flags)
|
pv_context_connect (PvContext *context, PvContextFlags flags)
|
||||||
{
|
{
|
||||||
PvContextPrivate *priv;
|
PvContextPrivate *priv;
|
||||||
GBusNameWatcherFlags nw_flags;
|
|
||||||
|
|
||||||
g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
|
g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE);
|
||||||
|
|
||||||
|
|
@ -493,18 +534,8 @@ pv_context_connect (PvContext *context, PvContextFlags flags)
|
||||||
priv->flags = flags;
|
priv->flags = flags;
|
||||||
|
|
||||||
context_set_state (context, PV_CONTEXT_STATE_CONNECTING);
|
context_set_state (context, PV_CONTEXT_STATE_CONNECTING);
|
||||||
|
g_main_context_invoke (priv->context, (GSourceFunc) do_connect, context);
|
||||||
|
|
||||||
nw_flags = G_BUS_NAME_WATCHER_FLAGS_NONE;
|
|
||||||
if (!(flags & PV_CONTEXT_FLAGS_NOAUTOSPAWN))
|
|
||||||
nw_flags = G_BUS_NAME_WATCHER_FLAGS_AUTO_START;
|
|
||||||
|
|
||||||
priv->id = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
|
||||||
PV_DBUS_SERVICE,
|
|
||||||
nw_flags,
|
|
||||||
on_name_appeared,
|
|
||||||
on_name_vanished,
|
|
||||||
context,
|
|
||||||
NULL);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -617,7 +648,7 @@ pv_context_get_state (PvContext *context)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_context_error:
|
* pv_context_get_error:
|
||||||
* @context: a #PvContext
|
* @context: a #PvContext
|
||||||
*
|
*
|
||||||
* Get the current error of @context or %NULL when the context state
|
* Get the current error of @context or %NULL when the context state
|
||||||
|
|
@ -626,7 +657,7 @@ pv_context_get_state (PvContext *context)
|
||||||
* Returns: the last error or %NULL
|
* Returns: the last error or %NULL
|
||||||
*/
|
*/
|
||||||
const GError *
|
const GError *
|
||||||
pv_context_error (PvContext *context)
|
pv_context_get_error (PvContext *context)
|
||||||
{
|
{
|
||||||
PvContextPrivate *priv;
|
PvContextPrivate *priv;
|
||||||
|
|
||||||
|
|
@ -636,22 +667,6 @@ pv_context_error (PvContext *context)
|
||||||
return priv->error;
|
return priv->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* pv_context_get_connection:
|
|
||||||
* @context: a #PvContext
|
|
||||||
*
|
|
||||||
* Get the #GDBusConnection of @context.
|
|
||||||
*
|
|
||||||
* Returns: the #GDBusConnection of @context or %NULL when not connected.
|
|
||||||
*/
|
|
||||||
GDBusConnection *
|
|
||||||
pv_context_get_connection (PvContext *context)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (PV_IS_CONTEXT (context), NULL);
|
|
||||||
|
|
||||||
return context->priv->connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDBusProxy *
|
GDBusProxy *
|
||||||
pv_context_find_source (PvContext *context, const gchar *name, GVariant *props)
|
pv_context_find_source (PvContext *context, const gchar *name, GVariant *props)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,9 @@ struct _PvContextClass {
|
||||||
/* normal GObject stuff */
|
/* normal GObject stuff */
|
||||||
GType pv_context_get_type (void);
|
GType pv_context_get_type (void);
|
||||||
|
|
||||||
PvContext * pv_context_new (const gchar *name, GVariant *properties);
|
PvContext * pv_context_new (GMainContext *ctx,
|
||||||
|
const gchar *name,
|
||||||
|
GVariant *properties);
|
||||||
|
|
||||||
gboolean pv_context_connect (PvContext *context, PvContextFlags flags);
|
gboolean pv_context_connect (PvContext *context, PvContextFlags flags);
|
||||||
gboolean pv_context_disconnect (PvContext *context);
|
gboolean pv_context_disconnect (PvContext *context);
|
||||||
|
|
@ -107,12 +109,7 @@ gboolean pv_context_register_source (PvContext *context, PvSource
|
||||||
gboolean pv_context_unregister_source (PvContext *context, PvSource *source);
|
gboolean pv_context_unregister_source (PvContext *context, PvSource *source);
|
||||||
|
|
||||||
PvContextState pv_context_get_state (PvContext *context);
|
PvContextState pv_context_get_state (PvContext *context);
|
||||||
const GError * pv_context_error (PvContext *context);
|
const GError * pv_context_get_error (PvContext *context);
|
||||||
|
|
||||||
GDBusConnection * pv_context_get_connection (PvContext *context);
|
|
||||||
|
|
||||||
GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props);
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
||||||
61
src/client/pv-introspect.c
Normal file
61
src/client/pv-introspect.c
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* 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 "client/pulsevideo.h"
|
||||||
|
|
||||||
|
#include "client/pv-context.h"
|
||||||
|
#include "client/pv-enumtypes.h"
|
||||||
|
#include "client/pv-subscribe.h"
|
||||||
|
|
||||||
|
#include "dbus/org-pulsevideo.h"
|
||||||
|
|
||||||
|
#include "client/pv-private.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pv_context_list_source_info:
|
||||||
|
* @context: a connected #PvContext
|
||||||
|
* @flags: extra #PvSourceInfoFlags
|
||||||
|
* @cb: a #PvSourceInfoCallback
|
||||||
|
* @cancelable: a #GCancellable
|
||||||
|
* @user_data: user data passed to @cb
|
||||||
|
*
|
||||||
|
* Call @cb for each source.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
pv_context_list_source_info (PvContext *context,
|
||||||
|
PvSourceInfoFlags flags,
|
||||||
|
PvSourceInfoCallback cb,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GList *walk;
|
||||||
|
PvContextPrivate *priv = context->priv;
|
||||||
|
|
||||||
|
for (walk = priv->sources; walk; walk = g_list_next (walk)) {
|
||||||
|
GDBusProxy *proxy = walk->data;
|
||||||
|
PvSourceInfo info;
|
||||||
|
|
||||||
|
info.name = pv_source1_get_name (PV_SOURCE1 (proxy));
|
||||||
|
info.properties = pv_source1_get_properties (PV_SOURCE1 (proxy));
|
||||||
|
info.state = pv_source1_get_state (PV_SOURCE1 (proxy));
|
||||||
|
|
||||||
|
cb (context, &info, user_data);
|
||||||
|
}
|
||||||
|
cb (context, NULL, user_data);
|
||||||
|
}
|
||||||
68
src/client/pv-introspect.h
Normal file
68
src/client/pv-introspect.h
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* 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_INTROSPECT_H__
|
||||||
|
#define __PV_INTROSPECT_H__
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <client/pv-context.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PvSourceInfo:
|
||||||
|
* @name: the name of the source
|
||||||
|
* @properties: the properties of the source
|
||||||
|
* @state: the current state of the source
|
||||||
|
*
|
||||||
|
* The source information
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
GVariant *properties;
|
||||||
|
PvSourceState state;
|
||||||
|
GVariant *capabilities;
|
||||||
|
} PvSourceInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PvSourceInfoFlags:
|
||||||
|
* @PV_SOURCE_INFO_FLAGS_NONE: no flags
|
||||||
|
* @PV_SOURCE_INFO_FLAGS_CAPABILITIES: include capabilities
|
||||||
|
*
|
||||||
|
* Extra flags to pass to pv_context_get_source_info_list.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PV_SOURCE_INFO_FLAGS_NONE = 0,
|
||||||
|
PV_SOURCE_INFO_FLAGS_CAPABILITIES = (1 << 0)
|
||||||
|
} PvSourceInfoFlags;
|
||||||
|
|
||||||
|
typedef gboolean (*PvSourceInfoCallback) (PvContext *c, const PvSourceInfo *info, gpointer userdata);
|
||||||
|
|
||||||
|
void pv_context_list_source_info (PvContext *context,
|
||||||
|
PvSourceInfoFlags flags,
|
||||||
|
PvSourceInfoCallback cb,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __PV_INTROSPECT_H__ */
|
||||||
|
|
||||||
48
src/client/pv-private.h
Normal file
48
src/client/pv-private.h
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _PvContextPrivate
|
||||||
|
{
|
||||||
|
GMainContext *context;
|
||||||
|
|
||||||
|
gchar *name;
|
||||||
|
GVariant *properties;
|
||||||
|
|
||||||
|
guint id;
|
||||||
|
GDBusConnection *connection;
|
||||||
|
|
||||||
|
PvContextFlags flags;
|
||||||
|
PvContextState state;
|
||||||
|
|
||||||
|
PvDaemon1 *daemon;
|
||||||
|
|
||||||
|
PvClient1 *client;
|
||||||
|
|
||||||
|
PvSubscriptionFlags subscription_mask;
|
||||||
|
PvSubscribe *subscribe;
|
||||||
|
|
||||||
|
GList *sources;
|
||||||
|
|
||||||
|
GDBusObjectManagerServer *server_manager;
|
||||||
|
|
||||||
|
GError *error;
|
||||||
|
};
|
||||||
|
|
||||||
|
GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props);
|
||||||
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include "dbus/org-pulsevideo.h"
|
#include "dbus/org-pulsevideo.h"
|
||||||
|
|
||||||
|
#include "client/pv-private.h"
|
||||||
|
|
||||||
struct _PvStreamPrivate
|
struct _PvStreamPrivate
|
||||||
{
|
{
|
||||||
PvContext *context;
|
PvContext *context;
|
||||||
|
|
@ -33,9 +35,11 @@ struct _PvStreamPrivate
|
||||||
GVariant *properties;
|
GVariant *properties;
|
||||||
gchar *target;
|
gchar *target;
|
||||||
PvStreamState state;
|
PvStreamState state;
|
||||||
|
GError *error;
|
||||||
|
|
||||||
gchar *source_output_path;
|
gchar *source_output_path;
|
||||||
PvSource1 *source;
|
PvSource1 *source;
|
||||||
|
GVariant *spec;
|
||||||
PvSourceOutput1 *source_output;
|
PvSourceOutput1 *source_output;
|
||||||
|
|
||||||
GSocket *socket;
|
GSocket *socket;
|
||||||
|
|
@ -303,6 +307,23 @@ pv_stream_get_state (PvStream *stream)
|
||||||
return stream->priv->state;
|
return stream->priv->state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pv_stream_get_error:
|
||||||
|
* @stream: a #PvStream
|
||||||
|
*
|
||||||
|
* Get the error of @stream.
|
||||||
|
*
|
||||||
|
* Returns: the error of @stream or %NULL when there is no error
|
||||||
|
*/
|
||||||
|
const GError *
|
||||||
|
pv_stream_get_error (PvStream *stream)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (PV_IS_STREAM (stream), NULL);
|
||||||
|
|
||||||
|
return stream->priv->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_request_reconfigure (PvSourceOutput1 *interface,
|
on_request_reconfigure (PvSourceOutput1 *interface,
|
||||||
GVariant *props,
|
GVariant *props,
|
||||||
|
|
@ -320,6 +341,8 @@ on_source_output1_proxy (GObject *source_object,
|
||||||
PvStreamPrivate *priv = stream->priv;
|
PvStreamPrivate *priv = stream->priv;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context->priv->context);
|
||||||
|
|
||||||
priv->source_output = pv_source_output1_proxy_new_finish (res, &error);
|
priv->source_output = pv_source_output1_proxy_new_finish (res, &error);
|
||||||
if (priv->source_output == NULL)
|
if (priv->source_output == NULL)
|
||||||
goto source_output_failed;
|
goto source_output_failed;
|
||||||
|
|
@ -331,9 +354,9 @@ on_source_output1_proxy (GObject *source_object,
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
source_output_failed:
|
source_output_failed:
|
||||||
{
|
{
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_error ("failed to get source output proxy: %s", error->message);
|
g_error ("failed to get source output proxy: %s", error->message);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -348,13 +371,15 @@ on_source_output_created (GObject *source_object,
|
||||||
PvContext *context = priv->context;
|
PvContext *context = priv->context;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context->priv->context);
|
||||||
|
|
||||||
if (!pv_source1_call_create_source_output_finish (priv->source,
|
if (!pv_source1_call_create_source_output_finish (priv->source,
|
||||||
&priv->source_output_path, res, &error))
|
&priv->source_output_path, res, &error))
|
||||||
goto create_failed;
|
goto create_failed;
|
||||||
|
|
||||||
g_print ("got source-output %s\n", priv->source_output_path);
|
g_print ("got source-output %s\n", priv->source_output_path);
|
||||||
|
|
||||||
pv_source_output1_proxy_new (pv_context_get_connection (context),
|
pv_source_output1_proxy_new (context->priv->connection,
|
||||||
G_DBUS_PROXY_FLAGS_NONE,
|
G_DBUS_PROXY_FLAGS_NONE,
|
||||||
g_dbus_proxy_get_name (G_DBUS_PROXY (priv->source)),
|
g_dbus_proxy_get_name (G_DBUS_PROXY (priv->source)),
|
||||||
priv->source_output_path,
|
priv->source_output_path,
|
||||||
|
|
@ -366,9 +391,9 @@ on_source_output_created (GObject *source_object,
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
create_failed:
|
create_failed:
|
||||||
{
|
{
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_print ("failed to get connect capture: %s", error->message);
|
g_print ("failed to get connect capture: %s", error->message);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -382,11 +407,13 @@ on_source_output_removed (GObject *source_object,
|
||||||
PvStreamPrivate *priv = stream->priv;
|
PvStreamPrivate *priv = stream->priv;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context->priv->context);
|
||||||
|
|
||||||
if (!pv_source_output1_call_remove_finish (priv->source_output,
|
if (!pv_source_output1_call_remove_finish (priv->source_output,
|
||||||
res, &error)) {
|
res, &error)) {
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_print ("failed to disconnect: %s", error->message);
|
g_print ("failed to disconnect: %s", error->message);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_clear_pointer (&priv->source_output_path, g_free);
|
g_clear_pointer (&priv->source_output_path, g_free);
|
||||||
|
|
@ -398,6 +425,8 @@ remove_source_output (PvStream *stream)
|
||||||
{
|
{
|
||||||
PvStreamPrivate *priv = stream->priv;
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context->priv->context);
|
||||||
|
|
||||||
pv_source_output1_call_remove (priv->source_output,
|
pv_source_output1_call_remove (priv->source_output,
|
||||||
NULL, /* GCancellable *cancellable */
|
NULL, /* GCancellable *cancellable */
|
||||||
on_source_output_removed,
|
on_source_output_removed,
|
||||||
|
|
@ -405,6 +434,21 @@ remove_source_output (PvStream *stream)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_connect_capture (PvStream *stream)
|
||||||
|
{
|
||||||
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
|
||||||
|
g_assert (g_main_context_get_thread_default () == priv->context->priv->context);
|
||||||
|
|
||||||
|
pv_source1_call_create_source_output (priv->source,
|
||||||
|
priv->spec, /* GVariant *arg_props */
|
||||||
|
NULL, /* GCancellable *cancellable */
|
||||||
|
on_source_output_created,
|
||||||
|
stream);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_stream_connect_capture:
|
* pv_stream_connect_capture:
|
||||||
* @stream: a #PvStream
|
* @stream: a #PvStream
|
||||||
|
|
@ -433,20 +477,17 @@ pv_stream_connect_capture (PvStream *stream,
|
||||||
|
|
||||||
priv->target = g_strdup (source);
|
priv->target = g_strdup (source);
|
||||||
|
|
||||||
stream_set_state (stream, PV_STREAM_STATE_CONNECTING);
|
|
||||||
|
|
||||||
priv->source = PV_SOURCE1 (pv_context_find_source (context, priv->target, NULL));
|
priv->source = PV_SOURCE1 (pv_context_find_source (context, priv->target, NULL));
|
||||||
if (priv->source == NULL) {
|
if (priv->source == NULL) {
|
||||||
g_warning ("can't find source");
|
g_warning ("can't find source");
|
||||||
stream_set_state (stream, PV_STREAM_STATE_READY);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
priv->spec = spec;
|
||||||
|
|
||||||
|
stream_set_state (stream, PV_STREAM_STATE_CONNECTING);
|
||||||
|
|
||||||
|
g_main_context_invoke (context->priv->context, (GSourceFunc) do_connect_capture, stream);
|
||||||
|
|
||||||
pv_source1_call_create_source_output (priv->source,
|
|
||||||
spec, /* GVariant *arg_props */
|
|
||||||
NULL, /* GCancellable *cancellable */
|
|
||||||
on_source_output_created,
|
|
||||||
stream);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -558,8 +599,7 @@ handle_socket (PvStream *stream, gint fd)
|
||||||
|
|
||||||
source = g_socket_create_source (priv->socket, G_IO_IN, NULL);
|
source = g_socket_create_source (priv->socket, G_IO_IN, NULL);
|
||||||
g_source_set_callback (source, (GSourceFunc) on_socket_data, stream, NULL);
|
g_source_set_callback (source, (GSourceFunc) on_socket_data, stream, NULL);
|
||||||
g_print ("%p\n", g_main_context_get_thread_default ());
|
priv->socket_id = g_source_attach (source, priv->context->priv->context);
|
||||||
priv->socket_id = g_source_attach (source, g_main_context_get_thread_default ());
|
|
||||||
g_source_unref (source);
|
g_source_unref (source);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -572,9 +612,9 @@ handle_socket (PvStream *stream, gint fd)
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
socket_failed:
|
socket_failed:
|
||||||
{
|
{
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_error ("failed to create socket: %s", error->message);
|
g_error ("failed to create socket: %s", error->message);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -645,12 +685,29 @@ fd_failed:
|
||||||
}
|
}
|
||||||
exit_error:
|
exit_error:
|
||||||
{
|
{
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_start (PvStream *stream)
|
||||||
|
{
|
||||||
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
GVariantBuilder builder;
|
||||||
|
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
|
g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string ("hello"));
|
||||||
|
|
||||||
|
pv_source_output1_call_start (priv->source_output,
|
||||||
|
g_variant_builder_end (&builder), /* GVariant *arg_properties */
|
||||||
|
NULL, /* GCancellable *cancellable */
|
||||||
|
on_stream_started,
|
||||||
|
stream);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pv_stream_start:
|
* pv_stream_start:
|
||||||
* @stream: a #PvStream
|
* @stream: a #PvStream
|
||||||
|
|
@ -680,18 +737,9 @@ pv_stream_start (PvStream *stream, PvStreamMode mode)
|
||||||
priv->mode = mode;
|
priv->mode = mode;
|
||||||
|
|
||||||
stream_set_state (stream, PV_STREAM_STATE_STARTING);
|
stream_set_state (stream, PV_STREAM_STATE_STARTING);
|
||||||
{
|
|
||||||
GVariantBuilder builder;
|
|
||||||
|
|
||||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
g_main_context_invoke (priv->context->priv->context, (GSourceFunc) do_start, stream);
|
||||||
g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string ("hello"));
|
|
||||||
|
|
||||||
pv_source_output1_call_start (priv->source_output,
|
|
||||||
g_variant_builder_end (&builder), /* GVariant *arg_properties */
|
|
||||||
NULL, /* GCancellable *cancellable */
|
|
||||||
on_stream_started,
|
|
||||||
stream);
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -717,13 +765,25 @@ on_stream_stopped (GObject *source_object,
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
call_failed:
|
call_failed:
|
||||||
{
|
{
|
||||||
|
priv->error = error;
|
||||||
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
stream_set_state (stream, PV_STREAM_STATE_ERROR);
|
||||||
g_error ("failed to release: %s", error->message);
|
g_error ("failed to release: %s", error->message);
|
||||||
g_clear_error (&error);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
do_stop (PvStream *stream)
|
||||||
|
{
|
||||||
|
PvStreamPrivate *priv = stream->priv;
|
||||||
|
|
||||||
|
pv_source_output1_call_stop (priv->source_output,
|
||||||
|
NULL, /* GCancellable *cancellable */
|
||||||
|
on_stream_stopped,
|
||||||
|
stream);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* pv_stream_stop:
|
* pv_stream_stop:
|
||||||
* @stream: a #PvStream
|
* @stream: a #PvStream
|
||||||
|
|
@ -742,10 +802,7 @@ pv_stream_stop (PvStream *stream)
|
||||||
priv = stream->priv;
|
priv = stream->priv;
|
||||||
g_return_val_if_fail (priv->state == PV_STREAM_STATE_STREAMING, FALSE);
|
g_return_val_if_fail (priv->state == PV_STREAM_STATE_STREAMING, FALSE);
|
||||||
|
|
||||||
pv_source_output1_call_stop (priv->source_output,
|
g_main_context_invoke (priv->context->priv->context, (GSourceFunc) do_stop, stream);
|
||||||
NULL, /* GCancellable *cancellable */
|
|
||||||
on_stream_stopped,
|
|
||||||
stream);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,7 @@ PvStream * pv_stream_new (PvContext * context,
|
||||||
GVariant * props);
|
GVariant * props);
|
||||||
|
|
||||||
PvStreamState pv_stream_get_state (PvStream *stream);
|
PvStreamState pv_stream_get_state (PvStream *stream);
|
||||||
|
const GError * pv_stream_get_error (PvStream *stream);
|
||||||
|
|
||||||
gboolean pv_stream_connect_capture (PvStream *stream,
|
gboolean pv_stream_connect_capture (PvStream *stream,
|
||||||
const gchar *source,
|
const gchar *source,
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,8 @@ on_sender_subscription_event (PvSubscribe *sender_subscribe,
|
||||||
SenderData *data = user_data;
|
SenderData *data = user_data;
|
||||||
PvSubscribe *subscribe = data->subscribe;
|
PvSubscribe *subscribe = data->subscribe;
|
||||||
|
|
||||||
|
g_print ("on sender subscription def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
g_signal_emit (subscribe,
|
g_signal_emit (subscribe,
|
||||||
signals[SIGNAL_SUBSCRIPTION_EVENT],
|
signals[SIGNAL_SUBSCRIPTION_EVENT],
|
||||||
0,
|
0,
|
||||||
|
|
@ -145,6 +147,11 @@ client_name_appeared_handler (GDBusConnection *connection,
|
||||||
{
|
{
|
||||||
SenderData *data = user_data;
|
SenderData *data = user_data;
|
||||||
|
|
||||||
|
g_print ("client name appeared def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
|
if (!g_strcmp0 (name, g_dbus_connection_get_unique_name (connection)))
|
||||||
|
return;
|
||||||
|
|
||||||
g_print ("appeared client %s %p\n", name, data);
|
g_print ("appeared client %s %p\n", name, data);
|
||||||
/* subscribe to Source events. We want to be notified when this new
|
/* subscribe to Source events. We want to be notified when this new
|
||||||
* sender add/change/remove sources and outputs */
|
* sender add/change/remove sources and outputs */
|
||||||
|
|
@ -215,6 +222,7 @@ sender_data_new (PvSubscribe *subscribe, const gchar *sender)
|
||||||
data->subscribe = subscribe;
|
data->subscribe = subscribe;
|
||||||
data->sender = g_strdup (sender);
|
data->sender = g_strdup (sender);
|
||||||
|
|
||||||
|
g_print ("watch name def: %p\n", g_main_context_get_thread_default ());
|
||||||
g_print ("watch name %s %p\n", sender, data);
|
g_print ("watch name %s %p\n", sender, data);
|
||||||
|
|
||||||
data->id = g_bus_watch_name_on_connection (priv->connection,
|
data->id = g_bus_watch_name_on_connection (priv->connection,
|
||||||
|
|
@ -239,6 +247,9 @@ notify_subscription (PvSubscribe *subscribe,
|
||||||
{
|
{
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
|
|
||||||
|
g_print ("notify subscription def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
//g_assert (g_main_context_get_thread_default ());
|
||||||
|
|
||||||
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_DAEMON) {
|
if (priv->subscription_mask & PV_SUBSCRIPTION_FLAGS_DAEMON) {
|
||||||
PvDaemon1 *daemon;
|
PvDaemon1 *daemon;
|
||||||
|
|
||||||
|
|
@ -384,6 +395,8 @@ client_manager_appeared (PvSubscribe *subscribe)
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
GList *objects, *walk;
|
GList *objects, *walk;
|
||||||
|
|
||||||
|
g_print ("client manager appeared def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager));
|
objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager));
|
||||||
for (walk = objects; walk ; walk = g_list_next (walk)) {
|
for (walk = objects; walk ; walk = g_list_next (walk)) {
|
||||||
on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager),
|
on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager),
|
||||||
|
|
@ -408,6 +421,8 @@ on_client_manager_name_owner (GObject *object,
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
gchar *name_owner;
|
gchar *name_owner;
|
||||||
|
|
||||||
|
g_print ("client manager owner def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
g_object_get (priv->client_manager, "name-owner", &name_owner, NULL);
|
g_object_get (priv->client_manager, "name-owner", &name_owner, NULL);
|
||||||
g_print ("client manager %s %s\n",
|
g_print ("client manager %s %s\n",
|
||||||
g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)),
|
g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)),
|
||||||
|
|
@ -427,6 +442,8 @@ connect_client_signals (PvSubscribe *subscribe)
|
||||||
{
|
{
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
|
|
||||||
|
g_print ("add signals def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
g_signal_connect (priv->client_manager, "notify::name-owner",
|
g_signal_connect (priv->client_manager, "notify::name-owner",
|
||||||
(GCallback) on_client_manager_name_owner, subscribe);
|
(GCallback) on_client_manager_name_owner, subscribe);
|
||||||
g_signal_connect (priv->client_manager, "interface-added",
|
g_signal_connect (priv->client_manager, "interface-added",
|
||||||
|
|
@ -452,6 +469,8 @@ on_client_manager_ready (GObject *source_object,
|
||||||
PvSubscribePrivate *priv = subscribe->priv;
|
PvSubscribePrivate *priv = subscribe->priv;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
|
g_print ("client manager ready def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
priv->client_manager = pv_object_manager_client_new_finish (res, &error);
|
priv->client_manager = pv_object_manager_client_new_finish (res, &error);
|
||||||
if (priv->client_manager == NULL)
|
if (priv->client_manager == NULL)
|
||||||
goto manager_error;
|
goto manager_error;
|
||||||
|
|
@ -481,6 +500,8 @@ install_subscription (PvSubscribe *subscribe)
|
||||||
|
|
||||||
subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_CONNECTING);
|
subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_CONNECTING);
|
||||||
|
|
||||||
|
g_print ("new client manager def: %p\n", g_main_context_get_thread_default ());
|
||||||
|
|
||||||
g_print ("new client manager for %s\n", priv->service);
|
g_print ("new client manager for %s\n", priv->service);
|
||||||
pv_object_manager_client_new (priv->connection,
|
pv_object_manager_client_new (priv->connection,
|
||||||
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
|
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ static void gst_pulsevideo_src_get_property (GObject * object, guint prop_id,
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
gst_pulsevideo_src_change_state (GstElement * element, GstStateChange transition);
|
gst_pulsevideo_src_change_state (GstElement * element, GstStateChange transition);
|
||||||
|
|
||||||
|
static gboolean gst_pulsevideo_src_negotiate (GstBaseSrc * basesrc);
|
||||||
static GstCaps *gst_pulsevideo_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
|
static GstCaps *gst_pulsevideo_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
|
||||||
static gboolean gst_pulsevideo_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
|
static gboolean gst_pulsevideo_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
|
||||||
static GstCaps *gst_pulsevideo_src_src_fixate (GstBaseSrc * bsrc,
|
static GstCaps *gst_pulsevideo_src_src_fixate (GstBaseSrc * bsrc,
|
||||||
|
|
@ -113,6 +114,7 @@ gst_pulsevideo_src_class_init (GstPulsevideoSrcClass * klass)
|
||||||
gst_element_class_add_pad_template (gstelement_class,
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
gst_static_pad_template_get (&gst_pulsevideo_src_template));
|
gst_static_pad_template_get (&gst_pulsevideo_src_template));
|
||||||
|
|
||||||
|
gstbasesrc_class->negotiate = gst_pulsevideo_src_negotiate;
|
||||||
gstbasesrc_class->get_caps = gst_pulsevideo_src_getcaps;
|
gstbasesrc_class->get_caps = gst_pulsevideo_src_getcaps;
|
||||||
gstbasesrc_class->set_caps = gst_pulsevideo_src_setcaps;
|
gstbasesrc_class->set_caps = gst_pulsevideo_src_setcaps;
|
||||||
gstbasesrc_class->fixate = gst_pulsevideo_src_src_fixate;
|
gstbasesrc_class->fixate = gst_pulsevideo_src_src_fixate;
|
||||||
|
|
@ -132,6 +134,8 @@ gst_pulsevideo_src_init (GstPulsevideoSrc * src)
|
||||||
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
gst_base_src_set_live (GST_BASE_SRC (src), TRUE);
|
||||||
|
|
||||||
src->fd_allocator = gst_fd_allocator_new ();
|
src->fd_allocator = gst_fd_allocator_new ();
|
||||||
|
g_mutex_init (&src->lock);
|
||||||
|
g_cond_init (&src->cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
|
@ -252,18 +256,9 @@ on_new_buffer (GObject *gobject,
|
||||||
{
|
{
|
||||||
GstPulsevideoSrc *pvsrc = user_data;
|
GstPulsevideoSrc *pvsrc = user_data;
|
||||||
|
|
||||||
g_main_loop_quit (pvsrc->loop);
|
g_mutex_lock (&pvsrc->lock);
|
||||||
}
|
g_cond_signal (&pvsrc->cond);
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
static void
|
|
||||||
on_socket_notify (GObject *gobject,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GSocket *socket;
|
|
||||||
|
|
||||||
g_object_get (gobject, "socket", &socket, NULL);
|
|
||||||
g_print ("got socket %p\n", socket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -274,30 +269,52 @@ on_stream_notify (GObject *gobject,
|
||||||
PvStreamState state;
|
PvStreamState state;
|
||||||
GstPulsevideoSrc *pvsrc = user_data;
|
GstPulsevideoSrc *pvsrc = user_data;
|
||||||
|
|
||||||
g_object_get (gobject, "state", &state, NULL);
|
g_mutex_lock (&pvsrc->lock);
|
||||||
|
state = pv_stream_get_state (pvsrc->stream);
|
||||||
g_print ("got stream state %d\n", state);
|
g_print ("got stream state %d\n", state);
|
||||||
|
if (state == PV_STREAM_STATE_ERROR) {
|
||||||
switch (state) {
|
GST_ELEMENT_ERROR (pvsrc, RESOURCE, FAILED,
|
||||||
case PV_STREAM_STATE_ERROR:
|
("Failed to connect stream: %s",
|
||||||
g_main_loop_quit (pvsrc->loop);
|
pv_stream_get_error (pvsrc->stream)->message), (NULL));
|
||||||
break;
|
|
||||||
case PV_STREAM_STATE_READY:
|
|
||||||
g_main_loop_quit (pvsrc->loop);
|
|
||||||
g_main_context_push_thread_default (pvsrc->context);
|
|
||||||
pv_stream_start (pvsrc->stream, PV_STREAM_MODE_BUFFER);
|
|
||||||
g_main_context_pop_thread_default (pvsrc->context);
|
|
||||||
break;
|
|
||||||
case PV_STREAM_STATE_STREAMING:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
g_cond_broadcast (&pvsrc->cond);
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
source_info_callback (PvContext *c, const PvSourceInfo *info, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstPulsevideoSrc *pvsrc = user_data;
|
||||||
|
|
||||||
|
if (info == NULL) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("source %s %p\n", info->name, pvsrc);
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_pulsevideo_src_negotiate (GstBaseSrc * basesrc)
|
||||||
|
{
|
||||||
|
GstPulsevideoSrc *pvsrc = GST_PULSEVIDEO_SRC (basesrc);
|
||||||
|
|
||||||
|
pv_context_list_source_info (pvsrc->ctx,
|
||||||
|
PV_SOURCE_INFO_FLAGS_CAPABILITIES,
|
||||||
|
source_info_callback,
|
||||||
|
NULL,
|
||||||
|
pvsrc);
|
||||||
|
|
||||||
|
return GST_BASE_SRC_CLASS (parent_class)->negotiate (basesrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_pulsevideo_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
|
gst_pulsevideo_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
|
||||||
{
|
{
|
||||||
return GST_BASE_SRC_CLASS (parent_class)->get_caps (bsrc, filter);
|
return GST_BASE_SRC_CLASS (parent_class)->get_caps (bsrc, filter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
@ -324,10 +341,8 @@ gst_pulsevideo_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
|
||||||
/* looks ok here */
|
/* looks ok here */
|
||||||
pvsrc->info = info;
|
pvsrc->info = info;
|
||||||
|
|
||||||
g_main_context_push_thread_default (pvsrc->context);
|
|
||||||
pvsrc->stream = pv_stream_new (pvsrc->ctx, "test", NULL);
|
pvsrc->stream = pv_stream_new (pvsrc->ctx, "test", NULL);
|
||||||
g_signal_connect (pvsrc->stream, "notify::state", (GCallback) on_stream_notify, pvsrc);
|
g_signal_connect (pvsrc->stream, "notify::state", (GCallback) on_stream_notify, pvsrc);
|
||||||
g_signal_connect (pvsrc->stream, "notify::socket", (GCallback) on_socket_notify, pvsrc);
|
|
||||||
g_signal_connect (pvsrc->stream, "new-buffer", (GCallback) on_new_buffer, pvsrc);
|
g_signal_connect (pvsrc->stream, "new-buffer", (GCallback) on_new_buffer, pvsrc);
|
||||||
|
|
||||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||||
|
|
@ -345,9 +360,22 @@ gst_pulsevideo_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
|
||||||
// g_variant_new_string (gst_video_interlace_mode_to_string (info.interlace_mode)));
|
// g_variant_new_string (gst_video_interlace_mode_to_string (info.interlace_mode)));
|
||||||
|
|
||||||
pv_stream_connect_capture (pvsrc->stream, NULL, 0, g_variant_builder_end (&builder));
|
pv_stream_connect_capture (pvsrc->stream, NULL, 0, g_variant_builder_end (&builder));
|
||||||
g_main_context_pop_thread_default (pvsrc->context);
|
|
||||||
|
|
||||||
g_main_loop_run (pvsrc->loop);
|
g_mutex_lock (&pvsrc->lock);
|
||||||
|
while (TRUE) {
|
||||||
|
PvStreamState state = pv_stream_get_state (pvsrc->stream);
|
||||||
|
|
||||||
|
if (state == PV_STREAM_STATE_READY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (state == PV_STREAM_STATE_ERROR)
|
||||||
|
goto connect_error;
|
||||||
|
|
||||||
|
g_cond_wait (&pvsrc->cond, &pvsrc->lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
|
||||||
|
pv_stream_start (pvsrc->stream, PV_STREAM_MODE_BUFFER);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pvsrc, "size %dx%d, %d/%d fps",
|
GST_DEBUG_OBJECT (pvsrc, "size %dx%d, %d/%d fps",
|
||||||
info.width, info.height, info.fps_n, info.fps_d);
|
info.width, info.height, info.fps_n, info.fps_d);
|
||||||
|
|
@ -365,6 +393,11 @@ unsupported_caps:
|
||||||
GST_DEBUG_OBJECT (bsrc, "unsupported caps: %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (bsrc, "unsupported caps: %" GST_PTR_FORMAT, caps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
connect_error:
|
||||||
|
{
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
@ -449,8 +482,10 @@ gst_pulsevideo_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
|
||||||
GST_VIDEO_FORMAT_UNKNOWN))
|
GST_VIDEO_FORMAT_UNKNOWN))
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
|
|
||||||
g_main_loop_run (pvsrc->loop);
|
g_mutex_lock (&pvsrc->lock);
|
||||||
|
g_cond_wait (&pvsrc->cond, &pvsrc->lock);
|
||||||
pv_stream_capture_buffer (pvsrc->stream, &info);
|
pv_stream_capture_buffer (pvsrc->stream, &info);
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
|
||||||
*buffer = gst_buffer_new ();
|
*buffer = gst_buffer_new ();
|
||||||
|
|
||||||
|
|
@ -494,6 +529,11 @@ gst_pulsevideo_src_stop (GstBaseSrc * basesrc)
|
||||||
static gpointer
|
static gpointer
|
||||||
handle_mainloop (GstPulsevideoSrc *this)
|
handle_mainloop (GstPulsevideoSrc *this)
|
||||||
{
|
{
|
||||||
|
g_main_context_push_thread_default (this->context);
|
||||||
|
g_print ("run mainloop\n");
|
||||||
|
g_main_loop_run (this->loop);
|
||||||
|
g_print ("quit mainloop\n");
|
||||||
|
g_main_context_pop_thread_default (this->context);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -506,36 +546,50 @@ on_state_notify (GObject *gobject,
|
||||||
GstPulsevideoSrc *pvsrc = user_data;
|
GstPulsevideoSrc *pvsrc = user_data;
|
||||||
PvContextState state;
|
PvContextState state;
|
||||||
|
|
||||||
g_object_get (gobject, "state", &state, NULL);
|
g_mutex_lock (&pvsrc->lock);
|
||||||
|
state = pv_context_get_state (pvsrc->ctx);
|
||||||
g_print ("got context state %d\n", state);
|
g_print ("got context state %d\n", state);
|
||||||
|
g_cond_broadcast (&pvsrc->cond);
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
|
||||||
switch (state) {
|
if (state == PV_CONTEXT_STATE_ERROR) {
|
||||||
case PV_CONTEXT_STATE_ERROR:
|
GST_ELEMENT_ERROR (pvsrc, RESOURCE, FAILED,
|
||||||
g_main_loop_quit (pvsrc->loop);
|
("Failed to connect stream: %s",
|
||||||
GST_ELEMENT_ERROR (pvsrc, RESOURCE, FAILED,
|
pv_context_get_error (pvsrc->ctx)->message), (NULL));
|
||||||
("Failed to connect stream: %s",
|
|
||||||
pv_context_error (pvsrc->ctx)->message), (NULL));
|
|
||||||
break;
|
|
||||||
case PV_CONTEXT_STATE_READY:
|
|
||||||
g_main_loop_quit (pvsrc->loop);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_pulsevideo_src_open (GstPulsevideoSrc * pvsrc)
|
gst_pulsevideo_src_open (GstPulsevideoSrc * pvsrc)
|
||||||
{
|
{
|
||||||
g_main_context_push_thread_default (pvsrc->context);
|
|
||||||
pvsrc->ctx = pv_context_new ("test-client", NULL);
|
|
||||||
g_signal_connect (pvsrc->ctx, "notify::state", (GCallback) on_state_notify, pvsrc);
|
|
||||||
pv_context_connect(pvsrc->ctx, PV_CONTEXT_FLAGS_NONE);
|
|
||||||
g_main_context_pop_thread_default (pvsrc->context);
|
|
||||||
|
|
||||||
g_main_loop_run (pvsrc->loop);
|
pvsrc->ctx = pv_context_new (pvsrc->context, "test-client", NULL);
|
||||||
|
g_signal_connect (pvsrc->ctx, "notify::state", (GCallback) on_state_notify, pvsrc);
|
||||||
|
|
||||||
|
pv_context_connect(pvsrc->ctx, PV_CONTEXT_FLAGS_NONE);
|
||||||
|
|
||||||
|
g_mutex_lock (&pvsrc->lock);
|
||||||
|
while (TRUE) {
|
||||||
|
PvContextState state = pv_context_get_state (pvsrc->ctx);
|
||||||
|
|
||||||
|
if (state == PV_CONTEXT_STATE_READY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (state == PV_CONTEXT_STATE_ERROR)
|
||||||
|
goto connect_error;
|
||||||
|
|
||||||
|
g_cond_wait (&pvsrc->cond, &pvsrc->lock);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
connect_error:
|
||||||
|
{
|
||||||
|
g_mutex_unlock (&pvsrc->lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
|
@ -552,7 +606,10 @@ gst_pulsevideo_src_change_state (GstElement * element, GstStateChange transition
|
||||||
this->thread = g_thread_new ("pulsevideo", (GThreadFunc) handle_mainloop, this);
|
this->thread = g_thread_new ("pulsevideo", (GThreadFunc) handle_mainloop, this);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
gst_pulsevideo_src_open (this);
|
if (!gst_pulsevideo_src_open (this)) {
|
||||||
|
ret = GST_STATE_CHANGE_FAILURE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||||
/* uncork and start recording */
|
/* uncork and start recording */
|
||||||
|
|
@ -568,7 +625,6 @@ gst_pulsevideo_src_change_state (GstElement * element, GstStateChange transition
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
g_main_loop_quit (this->loop);
|
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
break;
|
break;
|
||||||
|
|
@ -582,6 +638,7 @@ gst_pulsevideo_src_change_state (GstElement * element, GstStateChange transition
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <client/pv-context.h>
|
#include <client/pv-context.h>
|
||||||
#include <client/pv-stream.h>
|
#include <client/pv-stream.h>
|
||||||
|
#include <client/pv-introspect.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
@ -65,6 +66,9 @@ struct _GstPulsevideoSrc {
|
||||||
PvContext *ctx;
|
PvContext *ctx;
|
||||||
PvStream *stream;
|
PvStream *stream;
|
||||||
GstAllocator *fd_allocator;
|
GstAllocator *fd_allocator;
|
||||||
|
|
||||||
|
GMutex lock;
|
||||||
|
GCond cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPulsevideoSrcClass {
|
struct _GstPulsevideoSrcClass {
|
||||||
|
|
|
||||||
|
|
@ -147,14 +147,13 @@ name_acquired_handler (GDBusConnection *connection,
|
||||||
PvDaemonPrivate *priv = daemon->priv;
|
PvDaemonPrivate *priv = daemon->priv;
|
||||||
GDBusObjectManagerServer *manager = priv->server_manager;
|
GDBusObjectManagerServer *manager = priv->server_manager;
|
||||||
|
|
||||||
|
export_server_object (daemon, manager);
|
||||||
|
|
||||||
g_object_set (priv->subscribe, "service", PV_DBUS_SERVICE,
|
g_object_set (priv->subscribe, "service", PV_DBUS_SERVICE,
|
||||||
"subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL,
|
"subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL,
|
||||||
"connection", connection,
|
"connection", connection,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
|
||||||
export_server_object (daemon, manager);
|
|
||||||
|
|
||||||
g_dbus_object_manager_server_set_connection (manager, connection);
|
g_dbus_object_manager_server_set_connection (manager, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ main (gint argc, gchar *argv[])
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
c = pv_context_new ("test-client", NULL);
|
c = pv_context_new (NULL, "test-client", NULL);
|
||||||
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
||||||
pv_context_connect(c, PV_CONTEXT_FLAGS_NONE);
|
pv_context_connect(c, PV_CONTEXT_FLAGS_NONE);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ main (gint argc, gchar *argv[])
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
c = pv_context_new ("test-client", NULL);
|
c = pv_context_new (NULL, "test-client", NULL);
|
||||||
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
||||||
pv_context_connect(c, PV_CONTEXT_FLAGS_NOFAIL);
|
pv_context_connect(c, PV_CONTEXT_FLAGS_NOFAIL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ main (gint argc, gchar *argv[])
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
||||||
c = pv_context_new ("test-client", NULL);
|
c = pv_context_new (NULL, "test-client", NULL);
|
||||||
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
g_signal_connect (c, "notify::state", (GCallback) on_state_notify, c);
|
||||||
pv_context_connect(c, PV_CONTEXT_FLAGS_NONE);
|
pv_context_connect(c, PV_CONTEXT_FLAGS_NONE);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue