Improve error reporting

Pass GError around for things that can fail and report the errors back
to the client.

Improve shutdown of pipeline when no clients are consuming.

Make GStreamer elements handle all kinds of data and not just video
because we can.
This commit is contained in:
Wim Taymans 2015-05-15 13:34:32 +02:00
parent 4bc308835a
commit cbe7b52a70
13 changed files with 145 additions and 61 deletions

View file

@ -184,7 +184,8 @@ static PvSourceOutput *
client_create_source_output (PvSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix)
const gchar *prefix,
GError **error)
{
PvClientSourcePrivate *priv = PV_CLIENT_SOURCE (source)->priv;
PvSourceOutput *output;
@ -192,7 +193,15 @@ client_create_source_output (PvSource *source,
/* propose format of input */
g_object_get (priv->input, "format", &format_filter, NULL);
output = PV_SOURCE_CLASS (pv_client_source_parent_class)->create_source_output (source, client_path, format_filter, prefix);
output = PV_SOURCE_CLASS (pv_client_source_parent_class)
->create_source_output (source,
client_path,
format_filter,
prefix,
error);
if (output == NULL)
return NULL;
gst_element_set_state (priv->pipeline, GST_STATE_READY);
@ -246,7 +255,8 @@ PvSourceOutput *
pv_client_source_get_source_input (PvClientSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix)
const gchar *prefix,
GError **error)
{
PvClientSourcePrivate *priv;
@ -254,7 +264,15 @@ pv_client_source_get_source_input (PvClientSource *source,
priv = source->priv;
if (priv->input == NULL) {
priv->input = PV_SOURCE_CLASS (pv_client_source_parent_class)->create_source_output (PV_SOURCE (source), client_path, format_filter, prefix);
priv->input = PV_SOURCE_CLASS (pv_client_source_parent_class)
->create_source_output (PV_SOURCE (source),
client_path,
format_filter,
prefix,
error);
if (priv->input == NULL)
return NULL;
g_signal_connect (priv->input, "notify::socket", (GCallback) on_input_socket_notify, source);
}
return priv->input;

View file

@ -68,7 +68,8 @@ PvSource * pv_client_source_new (PvDaemon *daemon);
PvSourceOutput * pv_client_source_get_source_input (PvClientSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix);
const gchar *prefix,
GError **error);
G_END_DECLS

View file

@ -130,14 +130,23 @@ handle_create_source_output (PvClient1 *interface,
PvSourceOutput *output;
const gchar *object_path, *sender;
GBytes *formats;
GError *error = NULL;
formats = g_bytes_new (arg_accepted_formats, strlen (arg_accepted_formats) + 1);
source = pv_daemon_find_source (priv->daemon, arg_source, priv->properties, formats);
source = pv_daemon_find_source (priv->daemon,
arg_source,
priv->properties,
formats,
&error);
if (source == NULL)
goto no_source;
output = pv_source_create_source_output (source, priv->object_path, formats, priv->object_path);
output = pv_source_create_source_output (source,
priv->object_path,
formats,
priv->object_path,
&error);
if (output == NULL)
goto no_output;
@ -154,14 +163,16 @@ handle_create_source_output (PvClient1 *interface,
/* ERRORS */
no_source:
{
g_dbus_method_invocation_return_dbus_error (invocation,
"org.pulsevideo.Error", "Can't create source");
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_bytes_unref (formats);
return TRUE;
}
no_output:
{
g_dbus_method_invocation_return_dbus_error (invocation,
"org.pulsevideo.Error", "Can't create output");
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_bytes_unref (formats);
return TRUE;
}
}
@ -178,6 +189,7 @@ handle_create_source_input (PvClient1 *interface,
PvSourceOutput *input;
const gchar *source_input_path, *sender;
GBytes *formats;
GError *error = NULL;
source = pv_client_source_new (priv->daemon);
if (source == NULL)
@ -192,7 +204,8 @@ handle_create_source_input (PvClient1 *interface,
input = pv_client_source_get_source_input (PV_CLIENT_SOURCE (source),
priv->object_path,
formats,
priv->object_path);
priv->object_path,
&error);
if (input == NULL)
goto no_input;
@ -214,8 +227,9 @@ no_source:
}
no_input:
{
g_dbus_method_invocation_return_dbus_error (invocation,
"org.pulsevideo.Error", "Can't create input");
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_bytes_unref (formats);
return TRUE;
}
}

View file

@ -78,8 +78,6 @@ client_name_appeared_handler (GDBusConnection *connection,
SenderData *data = user_data;
PvDaemonPrivate *priv = data->daemon->priv;
g_print ("client name appeared def: %p\n", g_main_context_get_thread_default ());
g_hash_table_insert (priv->senders, data->sender, data);
if (!g_strcmp0 (name, g_dbus_connection_get_unique_name (connection)))
@ -121,7 +119,6 @@ sender_data_new (PvDaemon *daemon, const gchar *sender)
data->daemon = daemon;
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);
data->id = g_bus_watch_name_on_connection (priv->connection,
@ -371,15 +368,21 @@ PvSource *
pv_daemon_find_source (PvDaemon *daemon,
const gchar *name,
GVariant *props,
GBytes *format_filter)
GBytes *format_filter,
GError **error)
{
PvDaemonPrivate *priv;
g_return_val_if_fail (PV_IS_DAEMON (daemon), NULL);
priv = daemon->priv;
if (priv->sources == NULL)
if (priv->sources == NULL) {
if (error)
*error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"No sources registered");
return NULL;
}
return priv->sources->data;
}

View file

@ -78,7 +78,8 @@ void pv_daemon_remove_source (PvDaemon *daemon, PvSource *source
PvSource * pv_daemon_find_source (PvDaemon *daemon,
const gchar *name,
GVariant *props,
GBytes *format_filter);
GBytes *format_filter,
GError **error);
G_END_DECLS

View file

@ -271,14 +271,22 @@ output_unregister_object (PvSourceOutput *output)
pv_daemon_unexport (priv->daemon, priv->object_path);
}
static void
pv_source_output_dispose (GObject * object)
{
PvSourceOutput *output = PV_SOURCE_OUTPUT (object);
output_unregister_object (output);
G_OBJECT_CLASS (pv_source_output_parent_class)->dispose (object);
}
static void
pv_source_output_finalize (GObject * object)
{
PvSourceOutput *output = PV_SOURCE_OUTPUT (object);
PvSourceOutputPrivate *priv = output->priv;
output_unregister_object (output);
g_object_unref (priv->daemon);
g_object_unref (priv->iface);
g_free (priv->client_path);
@ -306,6 +314,7 @@ pv_source_output_class_init (PvSourceOutputClass * klass)
g_type_class_add_private (klass, sizeof (PvSourceOutputPrivate));
gobject_class->dispose = pv_source_output_dispose;
gobject_class->finalize = pv_source_output_finalize;
gobject_class->set_property = pv_source_output_set_property;
gobject_class->get_property = pv_source_output_get_property;

View file

@ -210,7 +210,6 @@ default_release_source_output (PvSource *source, PvSourceOutput *output)
return TRUE;
}
static void
pv_source_class_init (PvSourceClass * klass)
{
@ -354,7 +353,8 @@ PvSourceOutput *
pv_source_create_source_output (PvSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix)
const gchar *prefix,
GError **error)
{
PvSourceClass *klass;
PvSourceOutput *res;
@ -363,10 +363,16 @@ pv_source_create_source_output (PvSource *source,
klass = PV_SOURCE_GET_CLASS (source);
if (klass->create_source_output)
res = klass->create_source_output (source, client_path, format_filter, prefix);
else
if (klass->create_source_output) {
res = klass->create_source_output (source, client_path, format_filter, prefix, error);
} else {
if (error) {
*error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,
"Create SourceOutput not implemented");
}
res = NULL;
}
return res;
}

View file

@ -71,7 +71,8 @@ struct _PvSourceClass {
PvSourceOutput * (*create_source_output) (PvSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix);
const gchar *prefix,
GError **error);
gboolean (*release_source_output) (PvSource *source,
PvSourceOutput *output);
};
@ -90,7 +91,8 @@ void pv_source_report_error (PvSource *source, GError *err
PvSourceOutput * pv_source_create_source_output (PvSource *source,
const gchar *client_path,
GBytes *format_filter,
const gchar *prefix);
const gchar *prefix,
GError **error);
gboolean pv_source_release_source_output (PvSource *source, PvSourceOutput *output);
G_END_DECLS