From 155aa8555b436f547fb73c4de11164d4d166e80d Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 14 Jul 2016 13:25:16 +0200 Subject: GStreamer: improve QGstCodecsInfo - The class now works with GStreamer < 0.10.31. - New codecElement() function that returns the GStreamer encoder name for a given codec. - New codecOptions() function that returns the list of available GStreamer properties for a given codec. - Don't return duplicate codecs (when several GStreamer plugins are available for a given codec). We now only use the highest ranked one. Change-Id: I4a79099d4469907c73046d7e78df737fe4ed036c Reviewed-by: Christian Stromme --- src/gsttools/qgstcodecsinfo.cpp | 200 ++++++++++++++++++++++++++-------------- 1 file changed, 129 insertions(+), 71 deletions(-) (limited to 'src/gsttools') diff --git a/src/gsttools/qgstcodecsinfo.cpp b/src/gsttools/qgstcodecsinfo.cpp index edee797ae..230dc581b 100644 --- a/src/gsttools/qgstcodecsinfo.cpp +++ b/src/gsttools/qgstcodecsinfo.cpp @@ -41,62 +41,11 @@ #include "qgstutils_p.h" #include -#ifdef QMEDIA_GSTREAMER_CAMERABIN #include -#include -#endif - QGstCodecsInfo::QGstCodecsInfo(QGstCodecsInfo::ElementType elementType) { - -#if GST_CHECK_VERSION(0,10,31) - - GstElementFactoryListType gstElementType = 0; - switch (elementType) { - case AudioEncoder: - gstElementType = GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER; - break; - case VideoEncoder: - gstElementType = GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER; - break; - case Muxer: - gstElementType = GST_ELEMENT_FACTORY_TYPE_MUXER; - break; - } - - GstCaps *allCaps = supportedElementCaps(gstElementType); - GstCaps *caps = gst_caps_new_empty(); - - uint codecsCount = gst_caps_get_size(allCaps); - for (uint i=0; iname, "name") == 0 || strcmp(property->name, "parent") == 0) + continue; + + options.append(QLatin1String(property->name)); + } + g_free(properties); + gst_object_unref(element); + } + + return options; +} - Caps are simplified to mime type and a few field necessary to distinguish - different codecs like mpegversion or layer. - */ -GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementType, - GstRank minimumRank, - GstPadDirection padDirection) +void QGstCodecsInfo::updateCodecs(ElementType elementType) { - GList *elements = gst_element_factory_list_get_elements(elementType, minimumRank); - GstCaps *res = gst_caps_new_empty(); + m_codecs.clear(); + m_codecInfo.clear(); + + GList *elements = elementFactories(elementType); QSet fakeEncoderMimeTypes; fakeEncoderMimeTypes << "unknown/unknown" @@ -143,7 +118,7 @@ GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementT GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data; padTemplates = padTemplates->next; - if (padTemplate->direction == padDirection) { + if (padTemplate->direction == GST_PAD_SRC) { GstCaps *caps = gst_static_caps_get(&padTemplate->static_caps); for (uint i=0; i::const_iterator it = m_codecInfo.find(codec); + if (it == m_codecInfo.constEnd() || it->rank < rank) { + if (it == m_codecInfo.constEnd()) + m_codecs.append(codec); + + CodecInfo info; + info.elementName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory)); + + gchar *description = gst_pb_utils_get_codec_description(newCaps); + info.description = QString::fromUtf8(description); + if (description) + g_free(description); + + info.rank = rank; + + m_codecInfo.insert(codec, info); + } + + gst_caps_unref(newCaps); } gst_caps_unref(caps); } } } + gst_plugin_feature_list_free(elements); +} + +#if !GST_CHECK_VERSION(0, 10, 31) +static gboolean element_filter(GstPluginFeature *feature, gpointer user_data) +{ + if (Q_UNLIKELY(!GST_IS_ELEMENT_FACTORY(feature))) + return FALSE; + + const QGstCodecsInfo::ElementType type = *reinterpret_cast(user_data); + + const gchar *klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature)); + if (type == QGstCodecsInfo::AudioEncoder && !(strstr(klass, "Encoder") && strstr(klass, "Audio"))) + return FALSE; + if (type == QGstCodecsInfo::VideoEncoder && !(strstr(klass, "Encoder") && strstr(klass, "Video"))) + return FALSE; + if (type == QGstCodecsInfo::Muxer && !strstr(klass, "Muxer")) + return FALSE; + + guint rank = gst_plugin_feature_get_rank(feature); + if (rank < GST_RANK_MARGINAL) + return FALSE; + + return TRUE; +} + +static gint compare_plugin_func(const void *item1, const void *item2) +{ + GstPluginFeature *f1 = reinterpret_cast(const_cast(item1)); + GstPluginFeature *f2 = reinterpret_cast(const_cast(item2)); - return res; + gint diff = gst_plugin_feature_get_rank(f2) - gst_plugin_feature_get_rank(f1); + if (diff != 0) + return diff; + + return strcmp(gst_plugin_feature_get_name(f1), gst_plugin_feature_get_name (f2)); +} +#endif + +GList *QGstCodecsInfo::elementFactories(ElementType elementType) const +{ +#if GST_CHECK_VERSION(0,10,31) + GstElementFactoryListType gstElementType = 0; + switch (elementType) { + case AudioEncoder: + gstElementType = GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER; + break; + case VideoEncoder: + gstElementType = GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER; + break; + case Muxer: + gstElementType = GST_ELEMENT_FACTORY_TYPE_MUXER; + break; + } + + return gst_element_factory_list_get_elements(gstElementType, GST_RANK_MARGINAL); +#else + GList *result = gst_registry_feature_filter(gst_registry_get_default(), + element_filter, + FALSE, &elementType); + result = g_list_sort(result, compare_plugin_func); + return result; +#endif } -#endif //GST_CHECK_VERSION(0,10,31) -- cgit v1.2.3