From 8a7d5a7f8049af6a0ac67d6a2d9116db4473afaa Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 9 Dec 2015 13:27:43 +0100 Subject: [PATCH] gstpinos: add stream-properties Add a property to set the stream properties in the source and sink streams. --- src/gst/gstpinossink.c | 49 ++++++++++++++++++++++++++++++++++++++++-- src/gst/gstpinossink.h | 1 + src/gst/gstpinossrc.c | 47 +++++++++++++++++++++++++++++++++++++++- src/gst/gstpinossrc.h | 1 + src/server/source.c | 1 + 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/gst/gstpinossink.c b/src/gst/gstpinossink.c index 6e5a0968e..7a5f61f5a 100644 --- a/src/gst/gstpinossink.c +++ b/src/gst/gstpinossink.c @@ -51,7 +51,8 @@ GST_DEBUG_CATEGORY_STATIC (pinos_sink_debug); enum { PROP_0, - PROP_CLIENT_NAME + PROP_CLIENT_NAME, + PROP_STREAM_PROPERTIES }; @@ -90,6 +91,8 @@ gst_pinos_sink_finalize (GObject * object) { GstPinosSink *pinossink = GST_PINOS_SINK (object); + if (pinossink->properties) + gst_structure_free (pinossink->properties); g_hash_table_unref (pinossink->fdids); g_object_unref (pinossink->allocator); g_free (pinossink->client_name); @@ -130,6 +133,15 @@ gst_pinos_sink_class_init (GstPinosSinkClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_STREAM_PROPERTIES, + g_param_spec_boxed ("stream-properties", + "stream properties", + "list of pinos stream properties", + GST_TYPE_STRUCTURE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + gstelement_class->change_state = gst_pinos_sink_change_state; gst_element_class_set_static_metadata (gstelement_class, @@ -216,6 +228,13 @@ gst_pinos_sink_set_property (GObject * object, guint prop_id, pinossink->client_name = g_value_dup_string (value); break; + case PROP_STREAM_PROPERTIES: + if (pinossink->properties) + gst_structure_free (pinossink->properties); + pinossink->properties = + gst_structure_copy (gst_value_get_structure (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -233,6 +252,10 @@ gst_pinos_sink_get_property (GObject * object, guint prop_id, g_value_set_string (value, pinossink->client_name); break; + case PROP_STREAM_PROPERTIES: + gst_value_set_structure (value, pinossink->properties); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -308,20 +331,42 @@ gst_pinos_sink_getcaps (GstBaseSink * bsink, GstCaps * filter) return GST_BASE_SINK_CLASS (parent_class)->get_caps (bsink, filter); } +static gboolean +copy_properties (GQuark field_id, + const GValue *value, + gpointer user_data) +{ + PinosProperties *properties = user_data; + + if (G_VALUE_HOLDS_STRING (value)) + pinos_properties_set (properties, + g_quark_to_string (field_id), + g_value_get_string (value)); + return TRUE; +} + static gboolean gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) { GstPinosSink *pinossink; gchar *str; GBytes *format; + PinosProperties *props; pinossink = GST_PINOS_SINK (bsink); str = gst_caps_to_string (caps); format = g_bytes_new_take (str, strlen (str) + 1); + if (pinossink->properties) { + props = pinos_properties_new (NULL, NULL); + gst_structure_foreach (pinossink->properties, copy_properties, props); + } else { + props = NULL; + } + pinos_main_loop_lock (pinossink->loop); - pinossink->stream = pinos_stream_new (pinossink->ctx, pinossink->client_name, NULL); + pinossink->stream = pinos_stream_new (pinossink->ctx, pinossink->client_name, props); g_signal_connect (pinossink->stream, "notify::state", (GCallback) on_stream_notify, pinossink); g_signal_connect (pinossink->stream, "new-buffer", (GCallback) on_new_buffer, pinossink); diff --git a/src/gst/gstpinossink.h b/src/gst/gstpinossink.h index b02e8ae0f..c257f4264 100644 --- a/src/gst/gstpinossink.h +++ b/src/gst/gstpinossink.h @@ -62,6 +62,7 @@ struct _GstPinosSink { PinosContext *ctx; PinosStream *stream; GstAllocator *allocator; + GstStructure *properties; guint32 id_counter; GHashTable *fdids; diff --git a/src/gst/gstpinossrc.c b/src/gst/gstpinossrc.c index 61729d41a..3cecb0e6e 100644 --- a/src/gst/gstpinossrc.c +++ b/src/gst/gstpinossrc.c @@ -54,6 +54,7 @@ enum PROP_0, PROP_PATH, PROP_CLIENT_NAME, + PROP_STREAM_PROPERTIES, }; @@ -99,6 +100,13 @@ gst_pinos_src_set_property (GObject * object, guint prop_id, pinossrc->client_name = g_value_dup_string (value); break; + case PROP_STREAM_PROPERTIES: + if (pinossrc->properties) + gst_structure_free (pinossrc->properties); + pinossrc->properties = + gst_structure_copy (gst_value_get_structure (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -120,6 +128,10 @@ gst_pinos_src_get_property (GObject * object, guint prop_id, g_value_set_string (value, pinossrc->client_name); break; + case PROP_STREAM_PROPERTIES: + gst_value_set_structure (value, pinossrc->properties); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -158,6 +170,8 @@ gst_pinos_src_finalize (GObject * object) { GstPinosSrc *pinossrc = GST_PINOS_SRC (object); + if (pinossrc->properties) + gst_structure_free (pinossrc->properties); g_object_unref (pinossrc->fd_allocator); if (pinossrc->clock) gst_object_unref (pinossrc->clock); @@ -202,6 +216,15 @@ gst_pinos_src_class_init (GstPinosSrcClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_STREAM_PROPERTIES, + g_param_spec_boxed ("stream-properties", + "stream properties", + "list of pinos stream properties", + GST_TYPE_STRUCTURE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + gstelement_class->provide_clock = gst_pinos_src_provide_clock; gstelement_class->change_state = gst_pinos_src_change_state; @@ -736,10 +759,25 @@ on_context_notify (GObject *gobject, pinos_main_loop_signal (pinossrc->loop, FALSE); } +static gboolean +copy_properties (GQuark field_id, + const GValue *value, + gpointer user_data) +{ + PinosProperties *properties = user_data; + + if (G_VALUE_HOLDS_STRING (value)) + pinos_properties_set (properties, + g_quark_to_string (field_id), + g_value_get_string (value)); + return TRUE; +} + static gboolean gst_pinos_src_open (GstPinosSrc * pinossrc) { GError *error = NULL; + PinosProperties *props; pinossrc->context = g_main_context_new (); GST_DEBUG ("context %p", pinossrc->context); @@ -766,7 +804,14 @@ gst_pinos_src_open (GstPinosSrc * pinossrc) pinos_main_loop_wait (pinossrc->loop); } - pinossrc->stream = pinos_stream_new (pinossrc->ctx, pinossrc->client_name, NULL); + if (pinossrc->properties) { + props = pinos_properties_new (NULL, NULL); + gst_structure_foreach (pinossrc->properties, copy_properties, props); + } else { + props = NULL; + } + + pinossrc->stream = pinos_stream_new (pinossrc->ctx, pinossrc->client_name, props); g_signal_connect (pinossrc->stream, "notify::state", (GCallback) on_stream_notify, pinossrc); g_signal_connect (pinossrc->stream, "new-buffer", (GCallback) on_new_buffer, pinossrc); pinos_main_loop_unlock (pinossrc->loop); diff --git a/src/gst/gstpinossrc.h b/src/gst/gstpinossrc.h index 789648b20..de6925a75 100644 --- a/src/gst/gstpinossrc.h +++ b/src/gst/gstpinossrc.h @@ -63,6 +63,7 @@ struct _GstPinosSrc { PinosStream *stream; PinosStreamState stream_state; GstAllocator *fd_allocator; + GstStructure *properties; GstBuffer *current; GstClock *clock; diff --git a/src/server/source.c b/src/server/source.c index 7b5df7482..2cbfdea56 100644 --- a/src/server/source.c +++ b/src/server/source.c @@ -467,6 +467,7 @@ pinos_source_report_error (PinosSource *source, remove_idle_timeout (source); priv->error = error; priv->state = PINOS_SOURCE_STATE_ERROR; + g_debug ("got error state %s", error->message); pinos_source1_set_state (priv->iface, priv->state); g_object_notify (G_OBJECT (source), "state"); }