diff --git a/.gitignore b/.gitignore index fafe77e..eba0ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -93,4 +93,3 @@ /gstreamer-1.22.7.tar.xz /gstreamer-1.22.8.tar.xz /gstreamer-1.22.9.tar.xz -/gstreamer-1.23.1.tar.xz diff --git a/gstreamer-inspect-rpm-format.patch b/gstreamer-inspect-rpm-format.patch new file mode 100644 index 0000000..0114c06 --- /dev/null +++ b/gstreamer-inspect-rpm-format.patch @@ -0,0 +1,400 @@ +From 642d0d6fef226fb89eaecf0016f8e5e333b9023e Mon Sep 17 00:00:00 2001 +From: Wim Taymans +Date: Tue, 23 Jun 2015 10:28:29 +0200 +Subject: [PATCH] gst-inspect: add mode to output RPM requires format + +--- + tools/gst-inspect.c | 279 +++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 263 insertions(+), 16 deletions(-) + +diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c +index 8da042946..a057cba09 100644 +--- a/tools/gst-inspect.c ++++ b/tools/gst-inspect.c +@@ -394,7 +394,7 @@ print_object_properties_info (GObject * obj, GObjectClass * obj_class, + + first_flag = TRUE; + n_print ("%sflags%s: ", PROP_ATTR_NAME_COLOR, RESET_COLOR); +- readable = ! !(param->flags & G_PARAM_READABLE); ++ readable = !!(param->flags & G_PARAM_READABLE); + if (readable && obj != NULL) { + g_object_get_property (obj, param->name, &value); + } else { +@@ -1739,11 +1739,228 @@ print_tracer_info (GstPluginFeature * feature, gboolean print_names) + return 0; + } + ++static void ++print_gst_structure_append_field (GList * strings, const char *field) ++{ ++ GList *s; ++ ++ //g_message ("adding '%s' to the string", field); ++ ++ for (s = strings; s != NULL; s = s->next) { ++ g_string_append (s->data, field); ++ } ++} ++ ++static void ++print_gst_structure_append_field_index (GList * strings, const char *field, ++ guint num_items, guint offset) ++{ ++ GList *s; ++ guint i; ++ ++ //g_message ("adding '%s' to the string (num: %d offset: %d)", field, num_items, offset); ++ ++ for (s = strings, i = 0; s != NULL; s = s->next, i++) { ++ if (i == offset) { ++ //g_message ("adding '%s' at '%d'", field, i); ++ g_string_append (s->data, field); ++ } ++ if (i == num_items) ++ i = 0; ++ } ++ ++} ++ ++static GList * ++print_gst_structure_dup_fields (GList * strings, guint num_items) ++{ ++ guint new_items, i; ++ ++ if (num_items == 1) ++ return strings; ++ ++ //g_message ("creating %d new items", num_items); ++ ++ new_items = g_list_length (strings) * (num_items - 1); ++ for (i = 0; i < new_items; i++) { ++ GString *s, *first; ++ ++ first = strings->data; ++ s = g_string_new_len (first->str, first->len); ++ strings = g_list_prepend (strings, s); ++ } ++ ++ return strings; ++} ++ ++enum ++{ ++ FIELD_VERSION = 0, ++ FIELD_LAYER, ++ FIELD_VARIANT, ++ FIELD_SYSTEMSTREAM ++}; ++ ++static int ++field_get_type (const char *field_name) ++{ ++ if (strstr (field_name, "version") != NULL) ++ return FIELD_VERSION; ++ if (strcmp (field_name, "layer") == 0) ++ return FIELD_LAYER; ++ if (strcmp (field_name, "systemstream") == 0) ++ return FIELD_SYSTEMSTREAM; ++ if (strcmp (field_name, "variant") == 0) ++ return FIELD_VARIANT; ++ ++ return -1; ++} ++ ++static gint ++fields_type_compare (const char *a, const char *b) ++{ ++ gint a_type, b_type; ++ ++ a_type = field_get_type (a); ++ b_type = field_get_type (b); ++ if (a_type < b_type) ++ return -1; ++ if (b_type < a_type) ++ return 1; ++ return 0; ++} ++ ++static void ++print_gst_structure_for_rpm (const char *type_name, GstStructure * s) ++{ ++ guint i, num_fields; ++ const char *name; ++ GList *fields, *l, *strings; ++ GString *string; ++ ++ name = gst_structure_get_name (s); ++ strings = NULL; ++ num_fields = gst_structure_n_fields (s); ++ fields = NULL; ++ ++ for (i = 0; i < num_fields; i++) { ++ const char *field_name; ++ ++ field_name = gst_structure_nth_field_name (s, i); ++ if (field_get_type (field_name) < 0) { ++ //g_message ("ignoring field named %s", field_name); ++ continue; ++ } ++ ++ fields = ++ g_list_insert_sorted (fields, g_strdup (field_name), ++ (GCompareFunc) fields_type_compare); ++ } ++ ++ /* Example: ++ * gstreamer1(decoder-video/mpeg)(mpegversion=1)()(64bit) */ ++ string = g_string_new ("gstreamer1"); ++ g_string_append_c (string, '('); ++ g_string_append (string, type_name); ++ g_string_append_c (string, '-'); ++ g_string_append (string, name); ++ g_string_append_c (string, ')'); ++ ++ strings = g_list_append (strings, string); ++ ++ for (l = fields; l != NULL; l = l->next) { ++ char *field_name; ++ GType type; ++ ++ field_name = l->data; ++ ++ type = gst_structure_get_field_type (s, field_name); ++ //g_message ("field is: %s, type: %s", field_name, g_type_name (type)); ++ ++ if (type == G_TYPE_INT) { ++ char *field; ++ int value; ++ ++ gst_structure_get_int (s, field_name, &value); ++ field = g_strdup_printf ("(%s=%d)", field_name, value); ++ print_gst_structure_append_field (strings, field); ++ g_free (field); ++ } else if (type == G_TYPE_BOOLEAN) { ++ char *field; ++ int value; ++ ++ gst_structure_get_boolean (s, field_name, &value); ++ field = g_strdup_printf ("(%s=%s)", field_name, value ? "true" : "false"); ++ print_gst_structure_append_field (strings, field); ++ g_free (field); ++ } else if (type == GST_TYPE_INT_RANGE) { ++ const GValue *value; ++ int min, max; ++ ++ value = gst_structure_get_value (s, field_name); ++ min = gst_value_get_int_range_min (value); ++ max = gst_value_get_int_range_max (value); ++ ++ strings = print_gst_structure_dup_fields (strings, max - min + 1); ++ ++ for (i = min; i <= max; i++) { ++ char *field; ++ ++ field = g_strdup_printf ("(%s=%d)", field_name, i); ++ print_gst_structure_append_field_index (strings, field, max - min + 1, ++ i - min); ++ g_free (field); ++ } ++ } else if (type == GST_TYPE_LIST) { ++ const GValue *value; ++ int num_items; ++ ++ value = gst_structure_get_value (s, field_name); ++ num_items = gst_value_list_get_size (value); ++ ++ strings = print_gst_structure_dup_fields (strings, num_items); ++ ++ for (i = 0; i < num_items; i++) { ++ char *field; ++ const GValue *item_value; ++ ++ item_value = gst_value_list_get_value (value, i); ++ field = g_strdup_printf ("(%s=%d)", field_name, ++ g_value_get_int (item_value)); ++ print_gst_structure_append_field_index (strings, field, num_items, i); ++ g_free (field); ++ } ++ } else if (type == G_TYPE_STRING) { ++ char *field; ++ const char *value; ++ ++ value = gst_structure_get_string (s, field_name); ++ field = g_strdup_printf ("(%s=%s)", field_name, value); ++ print_gst_structure_append_field (strings, field); ++ g_free (field); ++ } else { ++ g_warning ("unhandled type! %s", g_type_name (type)); ++ } ++ ++ g_free (field_name); ++ } ++ ++ g_list_free (fields); ++ ++ for (l = strings; l != NULL; l = l->next) { ++ string = l->data; ++ g_print ("%s\n", string->str); ++ g_string_free (string, TRUE); ++ } ++ g_list_free (strings); ++} ++ + /* NOTE: Not coloring output from automatic install functions, as their output + * is meant for machines, not humans. + */ + static void +-print_plugin_automatic_install_info_codecs (GstElementFactory * factory) ++print_plugin_automatic_install_info_codecs (GstElementFactory * factory, ++ gboolean rpm_format) + { + GstPadDirection direction; + const gchar *type_name; +@@ -1769,6 +1986,13 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory) + return; + } + ++ if (rpm_format) { ++ /* Ignore NONE ranked plugins */ ++ if ((gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory))) == ++ GST_RANK_NONE) ++ return; ++ } ++ + /* decoder/demuxer sink pads should always be static and there should only + * be one, the same applies to encoders/muxers and source pads */ + static_templates = gst_element_factory_get_static_pad_templates (factory); +@@ -1805,15 +2029,20 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory) + gst_structure_remove_field (s, "rate"); + gst_structure_remove_field (s, "depth"); + gst_structure_remove_field (s, "clock-rate"); +- s_str = gst_structure_to_string (s); +- g_print ("%s-%s\n", type_name, s_str); +- g_free (s_str); ++ if (!rpm_format) { ++ s_str = gst_structure_to_string (s); ++ g_print ("%s-%s\n", type_name, s_str); ++ g_free (s_str); ++ } else { ++ print_gst_structure_for_rpm (type_name, s); ++ } + } + gst_caps_unref (caps); + } + + static void +-print_plugin_automatic_install_info_protocols (GstElementFactory * factory) ++print_plugin_automatic_install_info_protocols (GstElementFactory * factory, ++ gboolean rpm_format) + { + const gchar *const *protocols; + +@@ -1822,13 +2051,19 @@ print_plugin_automatic_install_info_protocols (GstElementFactory * factory) + switch (gst_element_factory_get_uri_type (factory)) { + case GST_URI_SINK: + while (*protocols != NULL) { +- g_print ("urisink-%s\n", *protocols); ++ if (!rpm_format) ++ g_print ("urisink-%s\n", *protocols); ++ else ++ g_print ("gstreamer1(urisink-%s)\n", *protocols); + ++protocols; + } + break; + case GST_URI_SRC: + while (*protocols != NULL) { +- g_print ("urisource-%s\n", *protocols); ++ if (!rpm_format) ++ g_print ("urisource-%s\n", *protocols); ++ else ++ g_print ("gstreamer1(urisource-%s)\n", *protocols); + ++protocols; + } + break; +@@ -1839,7 +2074,7 @@ print_plugin_automatic_install_info_protocols (GstElementFactory * factory) + } + + static void +-print_plugin_automatic_install_info (GstPlugin * plugin) ++print_plugin_automatic_install_info (GstPlugin * plugin, gboolean rpm_format) + { + GList *features, *l; + +@@ -1858,11 +2093,15 @@ print_plugin_automatic_install_info (GstPlugin * plugin) + if (feature_plugin == plugin) { + GstElementFactory *factory; + +- g_print ("element-%s\n", gst_plugin_feature_get_name (feature)); ++ if (!rpm_format) ++ g_print ("element-%s\n", gst_plugin_feature_get_name (feature)); ++ else ++ g_print ("gstreamer1(element-%s)\n", ++ gst_plugin_feature_get_name (feature)); + + factory = GST_ELEMENT_FACTORY (feature); +- print_plugin_automatic_install_info_protocols (factory); +- print_plugin_automatic_install_info_codecs (factory); ++ print_plugin_automatic_install_info_protocols (factory, rpm_format); ++ print_plugin_automatic_install_info_codecs (factory, rpm_format); + } + if (feature_plugin) + gst_object_unref (feature_plugin); +@@ -1884,7 +2123,7 @@ print_all_plugin_automatic_install_info (void) + plugin = (GstPlugin *) (plugins->data); + plugins = g_list_next (plugins); + +- print_plugin_automatic_install_info (plugin); ++ print_plugin_automatic_install_info (plugin, FALSE); + } + gst_plugin_list_free (orig_plugins); + } +@@ -1951,6 +2190,7 @@ main (int argc, char *argv[]) + gboolean do_print_blacklist = FALSE; + gboolean plugin_name = FALSE; + gboolean print_aii = FALSE; ++ gboolean print_aii_rpm = FALSE; + gboolean uri_handlers = FALSE; + gboolean check_exists = FALSE; + gboolean color_always = FALSE; +@@ -1972,6 +2212,9 @@ main (int argc, char *argv[]) + "or all plugins provide.\n " + "Useful in connection with external automatic plugin " + "installation mechanisms"), NULL}, ++ {"rpm", '\0', 0, G_OPTION_ARG_NONE, &print_aii_rpm, ++ N_("Print the machine-parsable list of features of a plugin in RPM " ++ "Provides compatible-format"), NULL}, + {"plugin", '\0', 0, G_OPTION_ARG_NONE, &plugin_name, + N_("List the plugin contents"), NULL}, + {"types", 't', 0, G_OPTION_ARG_STRING, &types, +@@ -2135,7 +2378,7 @@ main (int argc, char *argv[]) + /* if there is such a plugin, print out info */ + if (plugin) { + if (print_aii) { +- print_plugin_automatic_install_info (plugin); ++ print_plugin_automatic_install_info (plugin, print_aii_rpm); + } else { + print_plugin_info (plugin); + print_plugin_features (plugin); +@@ -2148,13 +2391,17 @@ main (int argc, char *argv[]) + + if (plugin) { + if (print_aii) { +- print_plugin_automatic_install_info (plugin); ++ print_plugin_automatic_install_info (plugin, print_aii_rpm); + } else { + print_plugin_info (plugin); + print_plugin_features (plugin); + } + } else { +- g_printerr (_("Could not load plugin file: %s\n"), error->message); ++ if (!print_aii_rpm) ++ g_print (_("Could not load plugin file: %s\n"), error->message); ++ else ++ g_printerr (_("Could not load plugin file: %s\n"), ++ error->message); + g_clear_error (&error); + exit_code = -1; + goto done; +-- +2.26.2 + diff --git a/gstreamer1.spec b/gstreamer1.spec index 1e2505f..96e625b 100644 --- a/gstreamer1.spec +++ b/gstreamer1.spec @@ -16,7 +16,7 @@ %endif Name: gstreamer1 -Version: 1.23.1 +Version: 1.22.9 Release: 1%{?dist} Summary: GStreamer streaming media framework runtime @@ -29,6 +29,8 @@ Source0: gstreamer-%{version}.tar.xz %else Source0: http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-%{version}.tar.xz %endif +## For GStreamer RPM provides +Patch0: gstreamer-inspect-rpm-format.patch Source1: gstreamer1.prov Source2: gstreamer1.attr @@ -48,7 +50,6 @@ BuildRequires: libunwind-devel %endif BuildRequires: elfutils-devel BuildRequires: bash-completion -BuildRequires: rust %description GStreamer is a streaming media framework, based on graphs of filters which @@ -86,6 +87,7 @@ GStreamer streaming media framework. %prep %setup -q -n gstreamer-%{version} +%patch -P 0 -p1 -b .rpm-provides %build %meson \ @@ -123,7 +125,6 @@ install -m0644 -D %{SOURCE2} $RPM_BUILD_ROOT%{_rpmconfigdir}/fileattrs/gstreamer %{_libexecdir}/gstreamer-%{majorminor}/gst-hotdoc-plugins-scanner %{_libexecdir}/gstreamer-%{majorminor}/gst-plugins-doc-cache-generator %{_libexecdir}/gstreamer-%{majorminor}/gst-plugin-scanner -%{_libexecdir}/gstreamer-%{majorminor}/gst-ptp-helper-test %attr(755,root,root) %caps(cap_net_bind_service,cap_net_admin,cap_sys_nice=ep) %{_libexecdir}/gstreamer-%{majorminor}/gst-ptp-helper %dir %{_libdir}/gstreamer-%{majorminor} @@ -199,9 +200,6 @@ install -m0644 -D %{SOURCE2} $RPM_BUILD_ROOT%{_rpmconfigdir}/fileattrs/gstreamer %changelog -* Wed Feb 07 2024 Gwyn Ciesla - 1.23.1-1 -- 1.23.1 - * Thu Jan 25 2024 Gwyn Ciesla - 1.22.9-1 - 1.22.9 diff --git a/sources b/sources index 48e38ae..38331b9 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gstreamer-1.23.1.tar.xz) = bf34f1787fe3e6400327c6cecf1122cdeacea30ce7c34c7018087e86e57c554601851c877293b0237f63869500dfb099d67010d93b8329faf2352db686ef64ff +SHA512 (gstreamer-1.22.9.tar.xz) = 67b8a87ac6d3db2d696589779f2931f3e4e330f6aa40611a221b8d42df923fb15e839eb828314ac24a25e18fa3efc328c3fca6c732ae41d08f247aa454ef5abb