diff --git a/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.c b/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.c index c2912518d4..ac1329804d 100644 --- a/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.c +++ b/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.c @@ -135,7 +135,8 @@ static gboolean gst_auto_convert_internal_src_event (GstPad * pad, GstObject * parent, GstEvent * event); static gboolean gst_auto_convert_internal_src_query (GstPad * pad, GstObject * parent, GstQuery * query); -static GList * gst_auto_convert_get_or_load_factories (GstAutoConvert * autoconvert); +static GList *gst_auto_convert_get_or_load_factories (GstAutoConvert * + autoconvert); static GQuark internal_srcpad_quark = 0; static GQuark internal_sinkpad_quark = 0; @@ -180,6 +181,23 @@ gst_auto_convert_class_init (GstAutoConvertClass * klass) " ownership of the list (NULL means it will go through all possible" " elements), can only be set once", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * autoconvert:factory-names: + * + * A #GstValueArray of factory names to use + * + * Since: 1.20 + */ + g_object_class_install_property (gobject_class, PROP_FACTORY_NAMES, + gst_param_spec_array ("factory-names", "Factory names" + "Names of the Factories to use", + "Names of the GstElementFactory to be used to automatically plug" + " elements.", + g_param_spec_string ("factory-name", "Factory name", + "An element factory name", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS), + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static void @@ -248,11 +266,20 @@ gst_auto_convert_set_property (GObject * object, break; case PROP_FACTORIES: { - GList *factories = g_value_get_pointer (value); + GList *factories; + GstAutoConvertClass *klass = GST_AUTO_CONVERT_GET_CLASS (autoconvert); + if (klass->load_factories) { + g_warning ("'factories' on %s is not read-only", + G_OBJECT_TYPE_NAME (object)); + break; + } + + factories = g_value_get_pointer (value); GST_OBJECT_LOCK (object); if (!autoconvert->factories) - autoconvert->factories = g_list_copy_deep (factories, (GCopyFunc) gst_object_ref, NULL); + autoconvert->factories = + g_list_copy_deep (factories, (GCopyFunc) gst_object_ref, NULL); else GST_WARNING_OBJECT (object, "Can not reset factories after they" " have been set or auto-discovered"); @@ -261,15 +288,23 @@ gst_auto_convert_set_property (GObject * object, } case PROP_FACTORY_NAMES: { + GstAutoConvertClass *klass = GST_AUTO_CONVERT_GET_CLASS (autoconvert); + + if (klass->load_factories) { + g_warning ("'factory-names' on %s is not read-only", + G_OBJECT_TYPE_NAME (object)); + break; + } + 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 - ); + 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), @@ -278,7 +313,8 @@ gst_auto_convert_set_property (GObject * object, continue; } - autoconvert->factories = g_list_append (autoconvert->factories, factory); + autoconvert->factories = + g_list_append (autoconvert->factories, factory); } } else { GST_WARNING_OBJECT (object, "Can not reset factories after they" @@ -930,16 +966,24 @@ static GList * gst_auto_convert_get_or_load_factories (GstAutoConvert * autoconvert) { GList *all_factories; + GstAutoConvertClass *klass = GST_AUTO_CONVERT_GET_CLASS (autoconvert); GST_OBJECT_LOCK (autoconvert); if (autoconvert->factories) goto done; + GST_OBJECT_UNLOCK (autoconvert); + if (klass->load_factories) { + all_factories = klass->load_factories (autoconvert); + } else { + all_factories = + g_list_sort (gst_registry_feature_filter (gst_registry_get (), + gst_auto_convert_default_filter_func, FALSE, NULL), + (GCompareFunc) compare_ranks); + } - all_factories = - gst_registry_feature_filter (gst_registry_get (), - gst_auto_convert_default_filter_func, FALSE, NULL); - autoconvert->factories = g_list_sort (all_factories, (GCompareFunc) compare_ranks); + GST_OBJECT_LOCK (autoconvert); + autoconvert->factories = all_factories; done: GST_OBJECT_UNLOCK (autoconvert); @@ -1167,7 +1211,6 @@ gst_auto_convert_getcaps (GstAutoConvert * autoconvert, GstCaps * filter, internal_sinkpad_quark); element_caps = gst_pad_peer_query_caps (internal_pad, filter); - if (element_caps) caps = gst_caps_merge (caps, element_caps); diff --git a/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.h b/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.h index 310dfb0228..cf4dc7a012 100644 --- a/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.h +++ b/subprojects/gst-plugins-bad/gst/autoconvert/gstautoconvert.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS #define GST_TYPE_AUTO_CONVERT (gst_auto_convert_get_type()) #define GST_AUTO_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AUTO_CONVERT,GstAutoConvert)) #define GST_AUTO_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AUTO_CONVERT,GstAutoConvertClass)) +#define GST_AUTO_CONVERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_AUTO_CONCERT, GstAutoConvertClass)) #define GST_IS_AUTO_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AUTO_CONVERT)) #define GST_IS_AUTO_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AUTO_CONVERT)) typedef struct _GstAutoConvert GstAutoConvert; @@ -58,8 +59,11 @@ struct _GstAutoConvert struct _GstAutoConvertClass { GstBinClass parent_class; + + GList* (*load_factories)(GstAutoConvert *autoconvert); }; +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAutoConvert, gst_object_unref) GType gst_auto_convert_get_type (void); GST_ELEMENT_REGISTER_DECLARE (autoconvert); diff --git a/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.c b/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.c index 9161965351..07ffb46be4 100644 --- a/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.c +++ b/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.c @@ -1,7 +1,7 @@ /* GStreamer - * Copyright 2010 ST-Ericsson SA + * Copyright 2010 ST-Ericsson SA * @author: Benjamin Gaignard - * + * * 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 @@ -37,27 +37,16 @@ GST_DEBUG_CATEGORY (autovideoconvert_debug); #define GST_CAT_DEFAULT (autovideoconvert_debug) -static GMutex factories_mutex; -static guint32 factories_cookie = 0; /* Cookie from last time when factories was updated */ -static GList *factories = NULL; /* factories we can use for selecting elements */ +struct _GstAutoVideoConvert +{ + GstAutoConvert parent; +}; -/* element factory information */ -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); +G_DEFINE_TYPE (GstAutoVideoConvert, gst_auto_video_convert, + GST_TYPE_AUTO_CONVERT); -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - - -static GstStateChangeReturn gst_auto_video_convert_change_state (GstElement * - element, GstStateChange transition); - -void gst_auto_video_convert_update_factory_list (GstAutoVideoConvert * - autovideoconvert); +GST_ELEMENT_REGISTER_DEFINE (autovideoconvert, "autovideoconvert", + GST_RANK_NONE, gst_auto_video_convert_get_type ()); static gboolean gst_auto_video_convert_element_filter (GstPluginFeature * feature, @@ -69,11 +58,15 @@ gst_auto_video_convert_element_filter (GstPluginFeature * feature, if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature))) return FALSE; + if (!g_strcmp0 (GST_OBJECT_NAME (feature), "autovideoconvert")) + return FALSE; + klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY_CAST (feature), GST_ELEMENT_METADATA_KLASS); /* only select color space converter */ - if (strstr (klass, "Filter") && - strstr (klass, "Converter") && strstr (klass, "Video")) { + if (strstr (klass, "Colorspace") && + strstr (klass, "Converter") && + strstr (klass, "Video")) { GST_DEBUG_OBJECT (autovideoconvert, "gst_auto_video_convert_element_filter found %s", gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (feature))); @@ -84,15 +77,14 @@ gst_auto_video_convert_element_filter (GstPluginFeature * feature, static GList * -gst_auto_video_convert_create_factory_list (GstAutoVideoConvert * - autovideoconvert) +gst_auto_video_convert_create_factory_list (GstAutoConvert * autoconvert) { GList *result = NULL; /* get the feature list using the filter */ result = gst_registry_feature_filter (gst_registry_get (), (GstPluginFeatureFilter) gst_auto_video_convert_element_filter, - FALSE, autovideoconvert); + FALSE, autoconvert); /* sort on rank and name */ result = g_list_sort (result, gst_plugin_feature_rank_compare_func); @@ -100,179 +92,24 @@ gst_auto_video_convert_create_factory_list (GstAutoVideoConvert * return result; } -void -gst_auto_video_convert_update_factory_list (GstAutoVideoConvert * - autovideoconvert) -{ - /* use a static mutex to protect factories list and factories cookie */ - g_mutex_lock (&factories_mutex); - - /* test if a factories list already exist or not */ - if (!factories) { - /* no factories list create it */ - factories_cookie = - gst_registry_get_feature_list_cookie (gst_registry_get ()); - factories = gst_auto_video_convert_create_factory_list (autovideoconvert); - } else { - /* a factories list exist but is it up to date? */ - if (factories_cookie != - gst_registry_get_feature_list_cookie (gst_registry_get ())) { - /* we need to update the factories list */ - /* first free the old one */ - gst_plugin_feature_list_free (factories); - /* then create an updated one */ - factories_cookie = - gst_registry_get_feature_list_cookie (gst_registry_get ()); - factories = gst_auto_video_convert_create_factory_list (autovideoconvert); - } - } - - g_mutex_unlock (&factories_mutex); -} - -G_DEFINE_TYPE (GstAutoVideoConvert, gst_auto_video_convert, GST_TYPE_BIN); -GST_ELEMENT_REGISTER_DEFINE (autovideoconvert, "autovideoconvert", - GST_RANK_NONE, GST_TYPE_AUTO_VIDEO_CONVERT); - static void gst_auto_video_convert_class_init (GstAutoVideoConvertClass * klass) { GstElementClass *gstelement_class = (GstElementClass *) klass; + ((GstAutoConvertClass *) klass)->load_factories = + gst_auto_video_convert_create_factory_list; GST_DEBUG_CATEGORY_INIT (autovideoconvert_debug, "autovideoconvert", 0, "Auto color space converter"); - gst_element_class_add_static_pad_template (gstelement_class, &srctemplate); - gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate); - gst_element_class_set_static_metadata (gstelement_class, - "Select color space converter based on caps", "Generic/Bin", + "Select color space converter and scalers based on caps", + "Bin/Colorspace/Scale/Video/Converter", "Selects the right color space converter based on the caps", "Benjamin Gaignard "); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_auto_video_convert_change_state); - -} - -static gboolean -gst_auto_video_convert_add_autoconvert (GstAutoVideoConvert * autovideoconvert) -{ - GstPad *pad; - - if (autovideoconvert->autoconvert) - return TRUE; - - autovideoconvert->autoconvert = - gst_element_factory_make ("autoconvert", NULL); - if (!autovideoconvert->autoconvert) { - GST_ERROR_OBJECT (autovideoconvert, - "Could not create autoconvert instance"); - return FALSE; - } - - /* first add autoconvert in bin */ - gst_bin_add (GST_BIN (autovideoconvert), - gst_object_ref (autovideoconvert->autoconvert)); - - /* get sinkpad and link it to ghost sink pad */ - pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "sink"); - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad), - pad); - gst_object_unref (pad); - - /* get srcpad and link it to ghost src pad */ - pad = gst_element_get_static_pad (autovideoconvert->autoconvert, "src"); - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad), pad); - gst_object_unref (pad); - - return TRUE; -} - -static void -gst_auto_video_convert_remove_autoconvert (GstAutoVideoConvert * - autovideoconvert) -{ - if (!autovideoconvert->autoconvert) - return; - - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->srcpad), - NULL); - gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (autovideoconvert->sinkpad), - NULL); - - gst_bin_remove (GST_BIN (autovideoconvert), autovideoconvert->autoconvert); - gst_object_unref (autovideoconvert->autoconvert); - autovideoconvert->autoconvert = NULL; } static void gst_auto_video_convert_init (GstAutoVideoConvert * autovideoconvert) { - GstPadTemplate *pad_tmpl; - - /* get sink pad template */ - pad_tmpl = gst_static_pad_template_get (&sinktemplate); - autovideoconvert->sinkpad = - gst_ghost_pad_new_no_target_from_template ("sink", pad_tmpl); - /* add sink ghost pad */ - gst_element_add_pad (GST_ELEMENT (autovideoconvert), - autovideoconvert->sinkpad); - gst_object_unref (pad_tmpl); - - /* get src pad template */ - pad_tmpl = gst_static_pad_template_get (&srctemplate); - autovideoconvert->srcpad = - gst_ghost_pad_new_no_target_from_template ("src", pad_tmpl); - /* add src ghost pad */ - gst_element_add_pad (GST_ELEMENT (autovideoconvert), - autovideoconvert->srcpad); - gst_object_unref (pad_tmpl); - - return; -} - -static GstStateChangeReturn -gst_auto_video_convert_change_state (GstElement * element, - GstStateChange transition) -{ - GstAutoVideoConvert *autovideoconvert = GST_AUTO_VIDEO_CONVERT (element); - GstStateChangeReturn ret; - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - { - /* create and add autoconvert in bin */ - if (!gst_auto_video_convert_add_autoconvert (autovideoconvert)) { - ret = GST_STATE_CHANGE_FAILURE; - return ret; - } - /* get an updated list of factories */ - gst_auto_video_convert_update_factory_list (autovideoconvert); - GST_DEBUG_OBJECT (autovideoconvert, "set factories list"); - /* give factory list to autoconvert */ - g_object_set (GST_ELEMENT (autovideoconvert->autoconvert), "factories", - factories, NULL); - break; - } - default: - break; - } - - ret = GST_ELEMENT_CLASS (gst_auto_video_convert_parent_class)->change_state - (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) - return ret; - - switch (transition) { - case GST_STATE_CHANGE_READY_TO_NULL: - { - gst_auto_video_convert_remove_autoconvert (autovideoconvert); - break; - } - default: - break; - } - - return ret; } diff --git a/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.h b/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.h index 8138993638..a0ecb9b650 100644 --- a/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.h +++ b/subprojects/gst-plugins-bad/gst/autoconvert/gstautovideoconvert.h @@ -1,7 +1,7 @@ /* GStreamer - * Copyright 2010 ST-Ericsson SA + * Copyright 2010 ST-Ericsson SA * @author: Benjamin Gaignard - * + * * 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 @@ -26,30 +26,8 @@ #include "gstautoconvert.h" G_BEGIN_DECLS -#define GST_TYPE_AUTO_VIDEO_CONVERT (gst_auto_video_convert_get_type()) -#define GST_AUTO_VIDEO_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AUTO_VIDEO_CONVERT,GstAutoVideoConvert)) -#define GST_AUTO_VIDEO_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AUTO_VIDEO_CONVERT,GstAutoVideoConvertClass)) -#define GST_IS_AUTO_VIDEO_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AUTO_VIDEO_CONVERT)) -#define GST_IS_AUTO_VIDEO_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AUTO_VIDEO_CONVERT)) -typedef struct _GstAutoVideoConvert GstAutoVideoConvert; -typedef struct _GstAutoVideoConvertClass GstAutoVideoConvertClass; -struct _GstAutoVideoConvert -{ - /*< private > */ - GstBin bin; /* we extend GstBin */ - - GstElement *autoconvert; - GstPad *sinkpad; - GstPad *srcpad; -}; - -struct _GstAutoVideoConvertClass -{ - GstBinClass parent_class; -}; - -GType gst_auto_video_convert_get_type (void); +G_DECLARE_FINAL_TYPE(GstAutoVideoConvert, gst_auto_video_convert, GST, AUTO_VIDEO_CONVERT, GstAutoConvert); GST_ELEMENT_REGISTER_DECLARE (autovideoconvert); G_END_DECLS