mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	gstpinos: add stream-properties
Add a property to set the stream properties in the source and sink streams.
This commit is contained in:
		
							parent
							
								
									c3fce0103b
								
							
						
					
					
						commit
						8a7d5a7f80
					
				
					 5 changed files with 96 additions and 3 deletions
				
			
		| 
						 | 
					@ -51,7 +51,8 @@ GST_DEBUG_CATEGORY_STATIC (pinos_sink_debug);
 | 
				
			||||||
enum
 | 
					enum
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  PROP_0,
 | 
					  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);
 | 
					  GstPinosSink *pinossink = GST_PINOS_SINK (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (pinossink->properties)
 | 
				
			||||||
 | 
					    gst_structure_free (pinossink->properties);
 | 
				
			||||||
  g_hash_table_unref (pinossink->fdids);
 | 
					  g_hash_table_unref (pinossink->fdids);
 | 
				
			||||||
  g_object_unref (pinossink->allocator);
 | 
					  g_object_unref (pinossink->allocator);
 | 
				
			||||||
  g_free (pinossink->client_name);
 | 
					  g_free (pinossink->client_name);
 | 
				
			||||||
| 
						 | 
					@ -130,6 +133,15 @@ gst_pinos_sink_class_init (GstPinosSinkClass * klass)
 | 
				
			||||||
                                                        G_PARAM_READWRITE |
 | 
					                                                        G_PARAM_READWRITE |
 | 
				
			||||||
                                                        G_PARAM_STATIC_STRINGS));
 | 
					                                                        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;
 | 
					  gstelement_class->change_state = gst_pinos_sink_change_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  gst_element_class_set_static_metadata (gstelement_class,
 | 
					  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);
 | 
					      pinossink->client_name = g_value_dup_string (value);
 | 
				
			||||||
      break;
 | 
					      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:
 | 
					    default:
 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
| 
						 | 
					@ -233,6 +252,10 @@ gst_pinos_sink_get_property (GObject * object, guint prop_id,
 | 
				
			||||||
      g_value_set_string (value, pinossink->client_name);
 | 
					      g_value_set_string (value, pinossink->client_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case PROP_STREAM_PROPERTIES:
 | 
				
			||||||
 | 
					      gst_value_set_structure (value, pinossink->properties);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
| 
						 | 
					@ -308,20 +331,42 @@ gst_pinos_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
 | 
				
			||||||
  return GST_BASE_SINK_CLASS (parent_class)->get_caps (bsink, 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
 | 
					static gboolean
 | 
				
			||||||
gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 | 
					gst_pinos_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GstPinosSink *pinossink;
 | 
					  GstPinosSink *pinossink;
 | 
				
			||||||
  gchar *str;
 | 
					  gchar *str;
 | 
				
			||||||
  GBytes *format;
 | 
					  GBytes *format;
 | 
				
			||||||
 | 
					  PinosProperties *props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinossink = GST_PINOS_SINK (bsink);
 | 
					  pinossink = GST_PINOS_SINK (bsink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  str = gst_caps_to_string (caps);
 | 
					  str = gst_caps_to_string (caps);
 | 
				
			||||||
  format = g_bytes_new_take (str, strlen (str) + 1);
 | 
					  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);
 | 
					  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, "notify::state", (GCallback) on_stream_notify, pinossink);
 | 
				
			||||||
  g_signal_connect (pinossink->stream, "new-buffer", (GCallback) on_new_buffer, pinossink);
 | 
					  g_signal_connect (pinossink->stream, "new-buffer", (GCallback) on_new_buffer, pinossink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,7 @@ struct _GstPinosSink {
 | 
				
			||||||
  PinosContext *ctx;
 | 
					  PinosContext *ctx;
 | 
				
			||||||
  PinosStream *stream;
 | 
					  PinosStream *stream;
 | 
				
			||||||
  GstAllocator *allocator;
 | 
					  GstAllocator *allocator;
 | 
				
			||||||
 | 
					  GstStructure *properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  guint32 id_counter;
 | 
					  guint32 id_counter;
 | 
				
			||||||
  GHashTable *fdids;
 | 
					  GHashTable *fdids;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,6 +54,7 @@ enum
 | 
				
			||||||
  PROP_0,
 | 
					  PROP_0,
 | 
				
			||||||
  PROP_PATH,
 | 
					  PROP_PATH,
 | 
				
			||||||
  PROP_CLIENT_NAME,
 | 
					  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);
 | 
					      pinossrc->client_name = g_value_dup_string (value);
 | 
				
			||||||
      break;
 | 
					      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:
 | 
					    default:
 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
| 
						 | 
					@ -120,6 +128,10 @@ gst_pinos_src_get_property (GObject * object, guint prop_id,
 | 
				
			||||||
      g_value_set_string (value, pinossrc->client_name);
 | 
					      g_value_set_string (value, pinossrc->client_name);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case PROP_STREAM_PROPERTIES:
 | 
				
			||||||
 | 
					      gst_value_set_structure (value, pinossrc->properties);
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
					      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
| 
						 | 
					@ -158,6 +170,8 @@ gst_pinos_src_finalize (GObject * object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GstPinosSrc *pinossrc = GST_PINOS_SRC (object);
 | 
					  GstPinosSrc *pinossrc = GST_PINOS_SRC (object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (pinossrc->properties)
 | 
				
			||||||
 | 
					    gst_structure_free (pinossrc->properties);
 | 
				
			||||||
  g_object_unref (pinossrc->fd_allocator);
 | 
					  g_object_unref (pinossrc->fd_allocator);
 | 
				
			||||||
  if (pinossrc->clock)
 | 
					  if (pinossrc->clock)
 | 
				
			||||||
    gst_object_unref (pinossrc->clock);
 | 
					    gst_object_unref (pinossrc->clock);
 | 
				
			||||||
| 
						 | 
					@ -202,6 +216,15 @@ gst_pinos_src_class_init (GstPinosSrcClass * klass)
 | 
				
			||||||
                                                        G_PARAM_READWRITE |
 | 
					                                                        G_PARAM_READWRITE |
 | 
				
			||||||
                                                        G_PARAM_STATIC_STRINGS));
 | 
					                                                        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->provide_clock = gst_pinos_src_provide_clock;
 | 
				
			||||||
  gstelement_class->change_state = gst_pinos_src_change_state;
 | 
					  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);
 | 
					  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
 | 
					static gboolean
 | 
				
			||||||
gst_pinos_src_open (GstPinosSrc * pinossrc)
 | 
					gst_pinos_src_open (GstPinosSrc * pinossrc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GError *error = NULL;
 | 
					  GError *error = NULL;
 | 
				
			||||||
 | 
					  PinosProperties *props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pinossrc->context = g_main_context_new ();
 | 
					  pinossrc->context = g_main_context_new ();
 | 
				
			||||||
  GST_DEBUG ("context %p", pinossrc->context);
 | 
					  GST_DEBUG ("context %p", pinossrc->context);
 | 
				
			||||||
| 
						 | 
					@ -766,7 +804,14 @@ gst_pinos_src_open (GstPinosSrc * pinossrc)
 | 
				
			||||||
    pinos_main_loop_wait (pinossrc->loop);
 | 
					    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, "notify::state", (GCallback) on_stream_notify, pinossrc);
 | 
				
			||||||
  g_signal_connect (pinossrc->stream, "new-buffer", (GCallback) on_new_buffer, pinossrc);
 | 
					  g_signal_connect (pinossrc->stream, "new-buffer", (GCallback) on_new_buffer, pinossrc);
 | 
				
			||||||
  pinos_main_loop_unlock (pinossrc->loop);
 | 
					  pinos_main_loop_unlock (pinossrc->loop);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,7 @@ struct _GstPinosSrc {
 | 
				
			||||||
  PinosStream *stream;
 | 
					  PinosStream *stream;
 | 
				
			||||||
  PinosStreamState stream_state;
 | 
					  PinosStreamState stream_state;
 | 
				
			||||||
  GstAllocator *fd_allocator;
 | 
					  GstAllocator *fd_allocator;
 | 
				
			||||||
 | 
					  GstStructure *properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GstBuffer *current;
 | 
					  GstBuffer *current;
 | 
				
			||||||
  GstClock *clock;
 | 
					  GstClock *clock;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -467,6 +467,7 @@ pinos_source_report_error (PinosSource *source,
 | 
				
			||||||
  remove_idle_timeout (source);
 | 
					  remove_idle_timeout (source);
 | 
				
			||||||
  priv->error = error;
 | 
					  priv->error = error;
 | 
				
			||||||
  priv->state = PINOS_SOURCE_STATE_ERROR;
 | 
					  priv->state = PINOS_SOURCE_STATE_ERROR;
 | 
				
			||||||
 | 
					  g_debug ("got error state %s", error->message);
 | 
				
			||||||
  pinos_source1_set_state (priv->iface, priv->state);
 | 
					  pinos_source1_set_state (priv->iface, priv->state);
 | 
				
			||||||
  g_object_notify (G_OBJECT (source), "state");
 | 
					  g_object_notify (G_OBJECT (source), "state");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue