mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
autoconvert: Add a 'factory-names' property
Making the element more gst-launch friendly. This also stop trying to handle usage of ->factories atomic and instead use the object lock to handle them. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/899>
This commit is contained in:
parent
1409826232
commit
8be2ae303a
3 changed files with 94 additions and 50 deletions
|
@ -4640,6 +4640,17 @@
|
||||||
"readable": true,
|
"readable": true,
|
||||||
"type": "gpointer",
|
"type": "gpointer",
|
||||||
"writable": true
|
"writable": true
|
||||||
|
},
|
||||||
|
"factory-names": {
|
||||||
|
"blurb": "Names of the GstElementFactory to be used to automatically plug elements.",
|
||||||
|
"conditionally-available": false,
|
||||||
|
"construct": false,
|
||||||
|
"construct-only": false,
|
||||||
|
"controllable": false,
|
||||||
|
"mutable": "null",
|
||||||
|
"readable": true,
|
||||||
|
"type": "GstValueArray",
|
||||||
|
"writable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rank": "none"
|
"rank": "none"
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gstautoconvert.h"
|
#include "gstautoconvert.h"
|
||||||
|
#include <gst/pbutils/pbutils.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -82,7 +83,8 @@ enum
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_FACTORIES
|
PROP_FACTORIES,
|
||||||
|
PROP_FACTORY_NAMES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gst_auto_convert_set_property (GObject * object,
|
static void gst_auto_convert_set_property (GObject * object,
|
||||||
|
@ -90,6 +92,7 @@ static void gst_auto_convert_set_property (GObject * object,
|
||||||
static void gst_auto_convert_get_property (GObject * object,
|
static void gst_auto_convert_get_property (GObject * object,
|
||||||
guint prop_id, GValue * value, GParamSpec * pspec);
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
static void gst_auto_convert_dispose (GObject * object);
|
static void gst_auto_convert_dispose (GObject * object);
|
||||||
|
static void gst_auto_convert_finalize (GObject * object);
|
||||||
|
|
||||||
static GstElement *gst_auto_convert_get_subelement (GstAutoConvert *
|
static GstElement *gst_auto_convert_get_subelement (GstAutoConvert *
|
||||||
autoconvert);
|
autoconvert);
|
||||||
|
@ -132,13 +135,7 @@ static gboolean gst_auto_convert_internal_src_event (GstPad * pad,
|
||||||
GstObject * parent, GstEvent * event);
|
GstObject * parent, GstEvent * event);
|
||||||
static gboolean gst_auto_convert_internal_src_query (GstPad * pad,
|
static gboolean gst_auto_convert_internal_src_query (GstPad * pad,
|
||||||
GstObject * parent, GstQuery * query);
|
GstObject * parent, GstQuery * query);
|
||||||
|
static GList * gst_auto_convert_get_or_load_factories (GstAutoConvert * autoconvert);
|
||||||
static GList *gst_auto_convert_load_factories (GstAutoConvert * autoconvert);
|
|
||||||
static GstElement
|
|
||||||
* gst_auto_convert_get_or_make_element_from_factory (GstAutoConvert *
|
|
||||||
autoconvert, GstElementFactory * factory);
|
|
||||||
static gboolean gst_auto_convert_activate_element (GstAutoConvert * autoconvert,
|
|
||||||
GstElement * element, GstCaps * caps);
|
|
||||||
|
|
||||||
static GQuark internal_srcpad_quark = 0;
|
static GQuark internal_srcpad_quark = 0;
|
||||||
static GQuark internal_sinkpad_quark = 0;
|
static GQuark internal_sinkpad_quark = 0;
|
||||||
|
@ -171,6 +168,7 @@ gst_auto_convert_class_init (GstAutoConvertClass * klass)
|
||||||
"Olivier Crete <olivier.crete@collabora.com>");
|
"Olivier Crete <olivier.crete@collabora.com>");
|
||||||
|
|
||||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_auto_convert_dispose);
|
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_auto_convert_dispose);
|
||||||
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_auto_convert_finalize);
|
||||||
|
|
||||||
gobject_class->set_property = gst_auto_convert_set_property;
|
gobject_class->set_property = gst_auto_convert_set_property;
|
||||||
gobject_class->get_property = gst_auto_convert_get_property;
|
gobject_class->get_property = gst_auto_convert_get_property;
|
||||||
|
@ -224,19 +222,20 @@ gst_auto_convert_dispose (GObject * object)
|
||||||
g_clear_object (&autoconvert->current_internal_srcpad);
|
g_clear_object (&autoconvert->current_internal_srcpad);
|
||||||
GST_AUTOCONVERT_UNLOCK (autoconvert);
|
GST_AUTOCONVERT_UNLOCK (autoconvert);
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
GList *factories = g_atomic_pointer_get (&autoconvert->factories);
|
|
||||||
|
|
||||||
if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories,
|
|
||||||
factories, NULL)) {
|
|
||||||
gst_plugin_feature_list_free (factories);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gst_auto_convert_parent_class)->dispose (object);
|
G_OBJECT_CLASS (gst_auto_convert_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_auto_convert_finalize (GObject * object)
|
||||||
|
{
|
||||||
|
GstAutoConvert *autoconvert = GST_AUTO_CONVERT (object);
|
||||||
|
|
||||||
|
if (autoconvert->factories)
|
||||||
|
gst_plugin_feature_list_free (autoconvert->factories);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (gst_auto_convert_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_auto_convert_set_property (GObject * object,
|
gst_auto_convert_set_property (GObject * object,
|
||||||
guint prop_id, const GValue * value, GParamSpec * pspec)
|
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||||
|
@ -248,19 +247,46 @@ gst_auto_convert_set_property (GObject * object,
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
case PROP_FACTORIES:
|
case PROP_FACTORIES:
|
||||||
if (g_atomic_pointer_get (&autoconvert->factories) == NULL) {
|
{
|
||||||
GList *factories = g_value_get_pointer (value);
|
GList *factories = g_value_get_pointer (value);
|
||||||
factories = g_list_copy (factories);
|
|
||||||
if (g_atomic_pointer_compare_and_exchange (&autoconvert->factories,
|
GST_OBJECT_LOCK (object);
|
||||||
(GList *) NULL, factories))
|
if (!autoconvert->factories)
|
||||||
g_list_foreach (factories, (GFunc) g_object_ref, NULL);
|
autoconvert->factories = g_list_copy_deep (factories, (GCopyFunc) gst_object_ref, NULL);
|
||||||
else
|
else
|
||||||
g_list_free (factories);
|
GST_WARNING_OBJECT (object, "Can not reset factories after they"
|
||||||
|
" have been set or auto-discovered");
|
||||||
|
GST_OBJECT_UNLOCK (object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PROP_FACTORY_NAMES:
|
||||||
|
{
|
||||||
|
GST_OBJECT_LOCK (object);
|
||||||
|
if (!autoconvert->factories) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < gst_value_array_get_size (value); i++) {
|
||||||
|
const GValue *v = gst_value_array_get_value (value, i);
|
||||||
|
GstElementFactory *factory = (GstElementFactory*) gst_registry_find_feature (
|
||||||
|
gst_registry_get (), g_value_get_string (v), GST_TYPE_ELEMENT_FACTORY
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!factory) {
|
||||||
|
gst_element_post_message (GST_ELEMENT_CAST (autoconvert),
|
||||||
|
gst_missing_element_message_new (GST_ELEMENT_CAST (autoconvert),
|
||||||
|
g_value_get_string (v)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
autoconvert->factories = g_list_append (autoconvert->factories, factory);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (object, "Can not reset factories after they"
|
GST_WARNING_OBJECT (object, "Can not reset factories after they"
|
||||||
" have been set or auto-discovered");
|
" have been set or auto-discovered");
|
||||||
}
|
}
|
||||||
|
GST_OBJECT_UNLOCK (object);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,9 +301,25 @@ gst_auto_convert_get_property (GObject * object,
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
case PROP_FACTORIES:
|
case PROP_FACTORIES:
|
||||||
g_value_set_pointer (value,
|
GST_OBJECT_LOCK (object);
|
||||||
g_atomic_pointer_get (&autoconvert->factories));
|
g_value_set_pointer (value, autoconvert->factories);
|
||||||
|
GST_OBJECT_UNLOCK (object);
|
||||||
break;
|
break;
|
||||||
|
case PROP_FACTORY_NAMES:
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (object);
|
||||||
|
for (tmp = autoconvert->factories; tmp; tmp = tmp->next) {
|
||||||
|
GValue factory = G_VALUE_INIT;
|
||||||
|
|
||||||
|
g_value_init (&factory, G_TYPE_STRING);
|
||||||
|
g_value_take_string (&factory, gst_object_get_name (tmp->data));
|
||||||
|
gst_value_array_append_and_take_value (value, &factory);
|
||||||
|
}
|
||||||
|
GST_OBJECT_UNLOCK (object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,11 +797,7 @@ gst_auto_convert_sink_setcaps (GstAutoConvert * autoconvert, GstCaps * caps)
|
||||||
}
|
}
|
||||||
|
|
||||||
other_caps = gst_pad_peer_query_caps (autoconvert->srcpad, NULL);
|
other_caps = gst_pad_peer_query_caps (autoconvert->srcpad, NULL);
|
||||||
|
factories = gst_auto_convert_get_or_load_factories (autoconvert);
|
||||||
factories = g_atomic_pointer_get (&autoconvert->factories);
|
|
||||||
|
|
||||||
if (!factories)
|
|
||||||
factories = gst_auto_convert_load_factories (autoconvert);
|
|
||||||
|
|
||||||
for (elem = factories; elem; elem = g_list_next (elem)) {
|
for (elem = factories; elem; elem = g_list_next (elem)) {
|
||||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (elem->data);
|
GstElementFactory *factory = GST_ELEMENT_FACTORY (elem->data);
|
||||||
|
@ -816,7 +854,6 @@ get_out:
|
||||||
* This function filters the pad pad templates, taking only transform element
|
* This function filters the pad pad templates, taking only transform element
|
||||||
* (with one sink and one src pad)
|
* (with one sink and one src pad)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_auto_convert_default_filter_func (GstPluginFeature * feature,
|
gst_auto_convert_default_filter_func (GstPluginFeature * feature,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
|
@ -890,24 +927,24 @@ compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
gst_auto_convert_load_factories (GstAutoConvert * autoconvert)
|
gst_auto_convert_get_or_load_factories (GstAutoConvert * autoconvert)
|
||||||
{
|
{
|
||||||
GList *all_factories;
|
GList *all_factories;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (autoconvert);
|
||||||
|
if (autoconvert->factories)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
|
||||||
all_factories =
|
all_factories =
|
||||||
gst_registry_feature_filter (gst_registry_get (),
|
gst_registry_feature_filter (gst_registry_get (),
|
||||||
gst_auto_convert_default_filter_func, FALSE, NULL);
|
gst_auto_convert_default_filter_func, FALSE, NULL);
|
||||||
|
autoconvert->factories = g_list_sort (all_factories, (GCompareFunc) compare_ranks);
|
||||||
|
|
||||||
all_factories = g_list_sort (all_factories, (GCompareFunc) compare_ranks);
|
done:
|
||||||
|
GST_OBJECT_UNLOCK (autoconvert);
|
||||||
|
|
||||||
g_assert (all_factories);
|
return autoconvert->factories;
|
||||||
|
|
||||||
if (!g_atomic_pointer_compare_and_exchange (&autoconvert->factories,
|
|
||||||
(GList *) NULL, all_factories)) {
|
|
||||||
gst_plugin_feature_list_free (all_factories);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_atomic_pointer_get (&autoconvert->factories);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In this case, we should almost always have an internal element, because
|
/* In this case, we should almost always have an internal element, because
|
||||||
|
@ -1090,11 +1127,7 @@ gst_auto_convert_getcaps (GstAutoConvert * autoconvert, GstCaps * filter,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
factories = g_atomic_pointer_get (&autoconvert->factories);
|
factories = gst_auto_convert_get_or_load_factories (autoconvert);
|
||||||
|
|
||||||
if (!factories)
|
|
||||||
factories = gst_auto_convert_load_factories (autoconvert);
|
|
||||||
|
|
||||||
for (elem = factories; elem; elem = g_list_next (elem)) {
|
for (elem = factories; elem; elem = g_list_next (elem)) {
|
||||||
GstElementFactory *factory = GST_ELEMENT_FACTORY (elem->data);
|
GstElementFactory *factory = GST_ELEMENT_FACTORY (elem->data);
|
||||||
GstElement *element = NULL;
|
GstElement *element = NULL;
|
||||||
|
|
|
@ -8,7 +8,7 @@ gstautoconvert = library('gstautoconvert',
|
||||||
autocon_sources,
|
autocon_sources,
|
||||||
c_args : gst_plugins_bad_args,
|
c_args : gst_plugins_bad_args,
|
||||||
include_directories : [configinc],
|
include_directories : [configinc],
|
||||||
dependencies : [gstbase_dep],
|
dependencies : [gstbase_dep, gstpbutils_dep],
|
||||||
install : true,
|
install : true,
|
||||||
install_dir : plugins_install_dir,
|
install_dir : plugins_install_dir,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue