From: Edward Hervey Date: Mon, 16 Aug 2010 17:01:15 +0000 (+0200) Subject: GstElementFactory: Add listing features X-Git-Tag: RELEASE-0.10.31~152 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=17f92542646a6a08b87093402e688f348f651f8d;p=platform%2Fupstream%2Fgstreamer.git GstElementFactory: Add listing features https://bugzilla.gnome.org/show_bug.cgi?id=626181 --- diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 361ed23..fd81982 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -648,6 +648,32 @@ gst_element_factory_make gst_element_factory_can_sink_caps gst_element_factory_can_src_caps gst_element_factory_get_static_pad_templates +GstElementFactoryListType +GST_ELEMENT_FACTORY_TYPE_ANY +GST_ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS +GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER +GST_ELEMENT_FACTORY_TYPE_DECODABLE +GST_ELEMENT_FACTORY_TYPE_DECODER +GST_ELEMENT_FACTORY_TYPE_DEMUXER +GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER +GST_ELEMENT_FACTORY_TYPE_ENCODER +GST_ELEMENT_FACTORY_TYPE_FORMATTER +GST_ELEMENT_FACTORY_TYPE_MAX_ELEMENTS +GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO +GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE +GST_ELEMENT_FACTORY_TYPE_MEDIA_METADATA +GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE +GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO +GST_ELEMENT_FACTORY_TYPE_MEDIA_ANY +GST_ELEMENT_FACTORY_TYPE_MUXER +GST_ELEMENT_FACTORY_TYPE_PARSER +GST_ELEMENT_FACTORY_TYPE_PAYLOADER +GST_ELEMENT_FACTORY_TYPE_SINK +GST_ELEMENT_FACTORY_TYPE_SRC +GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER +gst_element_factory_list_filter +gst_element_factory_list_get_elements +gst_element_factory_list_is_type GstElementFactoryClass GST_ELEMENT_FACTORY @@ -1814,7 +1840,9 @@ gst_plugin_feature_get_name gst_plugin_feature_load gst_plugin_feature_list_copy gst_plugin_feature_list_free +gst_plugin_feature_list_debug gst_plugin_feature_check_version +gst_plugin_feature_rank_compare_func GstPluginFeatureClass GST_PLUGIN_FEATURE diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 713c42b..d19d584 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -669,3 +669,199 @@ gst_element_factory_has_interface (GstElementFactory * factory, } return FALSE; } + + +typedef struct +{ + GstElementFactoryListType type; + GstRank minrank; +} FilterData; + + +/** + * gst_element_factory_list_is_type: + * @factory: a #GstElementFactory + * @type: a #GstElementFactoryListType + * + * Check if @factory if of the given types. + * + * Returns: %TRUE if @factory is of @type. + * + * Since: 0.10.31 + */ +gboolean +gst_element_factory_list_is_type (GstElementFactory * factory, + GstElementFactoryListType type) +{ + gboolean res = FALSE; + const gchar *klass; + + klass = gst_element_factory_get_klass (factory); + + /* Filter by element type first, as soon as it matches + * one type, we skip all other tests */ + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_SINK)) + res = (strstr (klass, "Sink") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_SRC)) + res = (strstr (klass, "Source") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_DECODER)) + res = (strstr (klass, "Decoder") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_ENCODER)) + res = (strstr (klass, "Encoder") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_MUXER)) + res = (strstr (klass, "Muxer") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_DEMUXER)) + res = (strstr (klass, "Demux") != NULL); + + /* FIXME : We're actually parsing two Classes here... */ + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_PARSER)) + res = ((strstr (klass, "Parser") != NULL) + && (strstr (klass, "Codec") != NULL)); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER)) + res = (strstr (klass, "Depayloader") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_PAYLOADER)) + res = (strstr (klass, "Payloader") != NULL); + + if (!res && (type & GST_ELEMENT_FACTORY_TYPE_FORMATTER)) + res = (strstr (klass, "Formatter") != NULL); + + /* Filter by media type now, we only test if it + * matched any of the types above. */ + if (res + && (type & (GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO | + GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | + GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE))) + res = ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) + && (strstr (klass, "Audio") != NULL)) + || ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO) + && (strstr (klass, "Video") != NULL)) + || ((type & GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE) + && (strstr (klass, "Image") != NULL)); + + return res; +} + +static gboolean +element_filter (GstPluginFeature * feature, FilterData * data) +{ + gboolean res; + + /* we only care about element factories */ + if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature))) + return FALSE; + + res = (gst_plugin_feature_get_rank (feature) >= data->minrank) && + gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (feature), + data->type); + + return res; +} + +/** + * gst_element_factory_list_get_elements: + * @type: a #GstElementFactoryListType + * @minrank: Minimum rank + * + * Get a list of factories that match the given @type. Only elements + * with a rank greater or equal to @minrank will be returned. + * The list of factories is returned by decreasing rank. + * + * Returns: a #GList of #GstElementFactory elements. Use + * gst_plugin_feature_list_free() after usage. + * + * Since: 0.10.31 + */ +GList * +gst_element_factory_list_get_elements (GstElementFactoryListType type, + GstRank minrank) +{ + GList *result; + FilterData data; + + /* prepare type */ + data.type = type; + data.minrank = minrank; + + /* get the feature list using the filter */ + result = gst_default_registry_feature_filter ((GstPluginFeatureFilter) + element_filter, FALSE, &data); + + /* sort on rank and name */ + result = g_list_sort (result, gst_plugin_feature_rank_compare_func); + + return result; +} + +/** + * gst_element_factory_list_filter: + * @list: a #GList of #GstElementFactory to filter + * @caps: a #GstCaps + * @direction: a #GstPadDirection to filter on + * @subsetonly: whether to filter on caps subsets or not. + * + * Filter out all the elementfactories in @list that can handle @caps in + * the given direction. + * + * If @subsetonly is %TRUE, then only the elements whose pads templates + * are a complete superset of @caps will be returned. Else any element + * whose pad templates caps can intersect with @caps will be returned. + * + * Returns: a #GList of #GstElementFactory elements that match the + * given requisits. Use #gst_plugin_feature_list_free after usage. + * + * Since: 0.10.31 + */ +GList * +gst_element_factory_list_filter (GList * list, + const GstCaps * caps, GstPadDirection direction, gboolean subsetonly) +{ + GList *result = NULL; + + GST_DEBUG ("finding factories"); + + /* loop over all the factories */ + for (; list; list = list->next) { + GstElementFactory *factory; + const GList *templates; + GList *walk; + + factory = (GstElementFactory *) list->data; + + GST_DEBUG ("Trying %s", + gst_plugin_feature_get_name ((GstPluginFeature *) factory)); + + /* get the templates from the element factory */ + templates = gst_element_factory_get_static_pad_templates (factory); + for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { + GstStaticPadTemplate *templ = walk->data; + + /* we only care about the sink templates */ + if (templ->direction == direction) { + GstCaps *tmpl_caps; + + /* try to intersect the caps with the caps of the template */ + tmpl_caps = gst_static_caps_get (&templ->static_caps); + + /* FIXME, intersect is not the right method, we ideally want to check + * for a subset here */ + + /* check if the intersection is empty */ + if ((subsetonly && gst_caps_is_subset (caps, tmpl_caps)) || + (!subsetonly && gst_caps_can_intersect (caps, tmpl_caps))) { + /* non empty intersection, we can use this element */ + result = g_list_prepend (result, gst_object_ref (factory)); + break; + } + gst_caps_unref (tmpl_caps); + } + } + } + return g_list_reverse (result); +} diff --git a/gst/gstelementfactory.h b/gst/gstelementfactory.h index 39772b0..1a71d73 100644 --- a/gst/gstelementfactory.h +++ b/gst/gstelementfactory.h @@ -165,8 +165,140 @@ void __gst_element_factory_add_interface (GstElementFacto gboolean gst_element_register (GstPlugin *plugin, const gchar *name, guint rank, GType type); +/* Factory list functions */ + +/** + * GstFactoryListType: + * @GST_ELEMENT_FACTORY_TYPE_DECODER: Decoder elements + * @GST_ELEMENT_FACTORY_TYPE_ENCODER: Encoder elements + * @GST_ELEMENT_FACTORY_TYPE_SINK: Sink elements + * @GST_ELEMENT_FACTORY_TYPE_SRC: Source elements + * @GST_ELEMENT_FACTORY_TYPE_MUXER: Muxer elements + * @GST_ELEMENT_FACTORY_TYPE_DEMUXER: Demuxer elements + * @GST_ELEMENT_FACTORY_TYPE_PARSER: Parser elements + * @GST_ELEMENT_FACTORY_TYPE_PAYLOADER: Payloader elements + * @GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER: Depayloader elements + * @GST_ELEMENT_FACTORY_TYPE_MAX_ELEMENTS: Private, do not use + * @GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO: Elements handling video media types + * @GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO: Elements handling audio media types + * @GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE: Elements handling image media types + * @GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE: Elements handling subtitle media types + * @GST_ELEMENT_FACTORY_TYPE_MEDIA_METADATA: Elements handling metadata media types + * + * The type of #GstElementFactory to filter. + * + * All @GstFactoryListType up to @GST_ELEMENT_FACTORY_TYPE_MAX_ELEMENTS are exclusive. + * + * If one or more of the MEDIA types are specified, then only elements + * matching the specified media types will be selected. + * + * Since: 0.10.31 + */ + +typedef guint64 GstElementFactoryListType; + +#define GST_ELEMENT_FACTORY_TYPE_DECODER (G_GUINT64_CONSTANT (1) << 0) +#define GST_ELEMENT_FACTORY_TYPE_ENCODER (G_GUINT64_CONSTANT (1) << 1) +#define GST_ELEMENT_FACTORY_TYPE_SINK (G_GUINT64_CONSTANT (1) << 2) +#define GST_ELEMENT_FACTORY_TYPE_SRC (G_GUINT64_CONSTANT (1) << 3) +#define GST_ELEMENT_FACTORY_TYPE_MUXER (G_GUINT64_CONSTANT (1) << 4) +#define GST_ELEMENT_FACTORY_TYPE_DEMUXER (G_GUINT64_CONSTANT (1) << 5) +#define GST_ELEMENT_FACTORY_TYPE_PARSER (G_GUINT64_CONSTANT (1) << 6) +#define GST_ELEMENT_FACTORY_TYPE_PAYLOADER (G_GUINT64_CONSTANT (1) << 7) +#define GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER (G_GUINT64_CONSTANT (1) << 8) +#define GST_ELEMENT_FACTORY_TYPE_FORMATTER (G_GUINT64_CONSTANT (1) << 9) + +#define GST_ELEMENT_FACTORY_TYPE_MAX_ELEMENTS (G_GUINT64_CONSTANT (1) << 48) + +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO (G_GUINT64_CONSTANT (1) << 49) +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO (G_GUINT64_CONSTANT (1) << 50) +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE (G_GUINT64_CONSTANT (1) << 51) +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE (G_GUINT64_CONSTANT (1) << 52) +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_METADATA (G_GUINT64_CONSTANT (1) << 53) + +/** + * GST_ELEMENT_FACTORY_TYPE_ANY: + * Elements of any of the defined GST_ELEMENT_FACTORY_LIST types + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_ANY G_GUINT64_CONSTANT ((1 << 49) - 1) + +/** + * GST_ELEMENT_FACTORY_TYPE_MEDIA_ANY: + * Elements matching any of the defined GST_ELEMENT_FACTORY_TYPE_MEDIA types + * + * Note: Do not use this if you wish to not filter against any of the defined + * media types. If you wish to do this, simply don't specify any + * GST_ELEMENT_FACTORY_TYPE_MEDIA flag. + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_MEDIA_ANY (~G_GUINT64_CONSTANT (0) << 48) + +/** + * GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER: + * All encoders handling video or image media types + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER (GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE) + +/** + * GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER: + * All encoders handling audio media types + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER (GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO) + +/** + * GST_ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS: + * + * All sinks handling audio, video or image media types + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS (GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO | GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE) + +/** + * GST_ELEMENT_FACTORY_TYPE_DECODABLE: + * + * All elements used to 'decode' streams (decoders, demuxers, parsers, depayloaders) + * + * Since: 0.10.31 + */ +#define GST_ELEMENT_FACTORY_TYPE_DECODABLE \ + (GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_DEMUXER | GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER | GST_ELEMENT_FACTORY_TYPE_PARSER) + +/* Element klass defines */ +#define GST_ELEMENT_FACTORY_KLASS_DECODER "Decoder" +#define GST_ELEMENT_FACTORY_KLASS_ENCODER "Encoder" +#define GST_ELEMENT_FACTORY_KLASS_SINK "Sink" +#define GST_ELEMENT_FACTORY_KLASS_SRC "Source" +#define GST_ELEMENT_FACTORY_KLASS_MUXER "Muxer" +#define GST_ELEMENT_FACTORY_KLASS_DEMUXER "Demuxer" +#define GST_ELEMENT_FACTORY_KLASS_PARSER "Parser" +#define GST_ELEMENT_FACTORY_KLASS_PAYLOADER "Payloader" +#define GST_ELEMENT_FACTORY_KLASS_DEPAYLOADER "Depayloader" +#define GST_ELEMENT_FACTORY_KLASS_FORMATTER "Formatter" + +#define GST_ELEMENT_FACTORY_KLASS_MEDIA_VIDEO "Video" +#define GST_ELEMENT_FACTORY_KLASS_MEDIA_AUDIO "Audio" +#define GST_ELEMENT_FACTORY_KLASS_MEDIA_IMAGE "Image" +#define GST_ELEMENT_FACTORY_KLASS_MEDIA_SUBTITLE "Subtitle" +#define GST_ELEMENT_FACTORY_KLASS_MEDIA_METADATA "Metadata" + +gboolean gst_element_factory_list_is_type (GstElementFactory *factory, + GstElementFactoryListType type); + +GList * gst_element_factory_list_get_elements (GstElementFactoryListType type, + GstRank minrank); +GList * gst_element_factory_list_filter (GList *list, const GstCaps *caps, + GstPadDirection direction, + gboolean subsetonly); G_END_DECLS #endif /* __GST_ELEMENT_FACTORY_H__ */ diff --git a/gst/gstpluginfeature.c b/gst/gstpluginfeature.c index 0ca7ab5..51961e5 100644 --- a/gst/gstpluginfeature.c +++ b/gst/gstpluginfeature.c @@ -296,6 +296,26 @@ gst_plugin_feature_list_copy (GList * list) } /** + * gst_plugin_feature_list_debug: + * @list: a #GList of plugin features + * + * Debug the plugin feature names in @list. + * + * Since: 0.10.31 + */ +void +gst_plugin_feature_list_debug (GList * list) +{ +#ifndef GST_DISABLE_GST_DEBUG + while (list) { + GST_DEBUG ("%s", + gst_plugin_feature_get_name ((GstPluginFeature *) list->data)); + list = list->next; + } +#endif +} + +/** * gst_plugin_feature_check_version: * @feature: a feature * @min_major: minimum required major version @@ -368,3 +388,36 @@ gst_plugin_feature_check_version (GstPluginFeature * feature, return ret; } + +/** + * gst_plugin_feature_rank_compare_func: + * @p1: a #GstPluginFeature + * @p2: a #GstPluginFeature + * + * Compares the two given #GstPluginFeature instances. This function can be + * used as a #GCompareFunc when sorting by rank and then by name. + * + * Returns: negative value if the rank of p1 > the rank of p2 or the ranks are + * equal but the name of p1 comes before the name of p2; zero if the rank + * and names are equal; positive value if the rank of p1 < the rank of p2 or the + * ranks are equal but the name of p2 comes after the name of p1 + * + * Since: 0.10.31 + */ +gint +gst_plugin_feature_rank_compare_func (gconstpointer p1, gconstpointer p2) +{ + GstPluginFeature *f1, *f2; + gint diff; + + f1 = (GstPluginFeature *) p1; + f2 = (GstPluginFeature *) p2; + + diff = f2->rank - f1->rank; + if (diff != 0) + return diff; + + diff = strcmp (f2->name, f1->name); + + return diff; +} diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h index ee1a6ce..ee615d9 100644 --- a/gst/gstpluginfeature.h +++ b/gst/gstpluginfeature.h @@ -138,11 +138,20 @@ G_CONST_RETURN gchar *gst_plugin_feature_get_name (GstPluginFeature *featu void gst_plugin_feature_list_free (GList *list); GList *gst_plugin_feature_list_copy (GList *list); +void gst_plugin_feature_list_debug (GList *list); + +#ifndef GST_DISABLE_GST_DEBUG +#define GST_PLUGIN_FEATURE_LIST_DEBUG(list) gst_plugin_feature_list_debug(list) +#else +#define GST_PLUGIN_FEATURE_LIST_DEBUG(list) +#endif gboolean gst_plugin_feature_check_version (GstPluginFeature *feature, guint min_major, guint min_minor, guint min_micro); +gint gst_plugin_feature_rank_compare_func (gconstpointer p1, + gconstpointer p2); G_END_DECLS