API: add gst_missing_*_installer_detail_new() convenience API so that applications...
authorTim-Philipp Müller <tim@centricular.net>
Tue, 28 Aug 2007 14:23:55 +0000 (14:23 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Tue, 28 Aug 2007 14:23:55 +0000 (14:23 +0000)
Original commit message from CVS:
* docs/libs/gst-plugins-base-libs-sections.txt:
* gst-libs/gst/pbutils/missing-plugins.c:
* gst-libs/gst/pbutils/missing-plugins.h:
* tests/check/libs/pbutils.c:
API: add gst_missing_*_installer_detail_new() convenience API so
that applications that know exactly what they're missing can request
installer detail strings for those items directly instead of having
to first create a dummy missing-plugin message and then get the
installer detail string from that.  Fixes #470456.

ChangeLog
docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/pbutils/missing-plugins.c
gst-libs/gst/pbutils/missing-plugins.h
tests/check/libs/pbutils.c

index 94b846f..12f5957 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-08-28  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * docs/libs/gst-plugins-base-libs-sections.txt:
+       * gst-libs/gst/pbutils/missing-plugins.c:
+       * gst-libs/gst/pbutils/missing-plugins.h:
+       * tests/check/libs/pbutils.c:
+         API: add gst_missing_*_installer_detail_new() convenience API so
+         that applications that know exactly what they're missing can request
+         installer detail strings for those items directly instead of having
+         to first create a dummy missing-plugin message and then get the
+         installer detail string from that.  Fixes #470456.
+
 2007-08-27  Jan Schmidt  <thaytan@mad.scientist.com>
 
        * gst/playback/gstdecodebin.c: (close_pad_link):
index e9b8d31..ad39354 100644 (file)
@@ -1258,6 +1258,12 @@ gst_missing_encoder_message_new
 gst_missing_uri_source_message_new
 gst_missing_uri_sink_message_new
 gst_missing_element_message_new
+<SUBSECTION>
+gst_missing_uri_source_installer_detail_new
+gst_missing_uri_sink_installer_detail_new
+gst_missing_element_installer_detail_new
+gst_missing_decoder_installer_detail_new
+gst_missing_encoder_installer_detail_new
 </SECTION>
 
 <SECTION>
index c139907..f78cfc8 100644 (file)
@@ -415,6 +415,7 @@ gst_missing_plugin_message_get_installer_detail (GstMessage * msg)
   type = gst_structure_get_string (msg->structure, "type");
   g_assert (type != NULL);      /* validity already checked above */
 
+  /* FIXME: use gst_installer_detail_new() here too */
   str = g_string_new (GST_DETAIL_STRING_MARKER "|");
   g_string_append_printf (str, "%u.%u|", GST_VERSION_MAJOR, GST_VERSION_MINOR);
 
@@ -594,3 +595,204 @@ gst_is_missing_plugin_message (GstMessage * msg)
 
   return gst_structure_has_name (msg->structure, "missing-plugin");
 }
+
+/* takes ownership of the description */
+static gchar *
+gst_installer_detail_new (gchar * description, const gchar * type,
+    const gchar * detail)
+{
+  const gchar *progname;
+  GString *s;
+
+  s = g_string_new (GST_DETAIL_STRING_MARKER "|");
+  g_string_append_printf (s, "%u.%u|", GST_VERSION_MAJOR, GST_VERSION_MINOR);
+
+  progname = (const gchar *) g_get_prgname ();
+  if (progname) {
+    g_string_append_printf (s, "%s|", progname);
+  } else {
+    g_string_append_printf (s, "pid/%lu|", (gulong) getpid ());
+  }
+
+  if (description) {
+    g_strdelimit (description, "|", '#');
+    g_string_append_printf (s, "%s|", description);
+    g_free (description);
+  } else {
+    g_string_append (s, "|");
+  }
+
+  g_string_append_printf (s, "%s-%s", type, detail);
+
+  return g_string_free (s, FALSE);
+}
+
+/**
+ * gst_missing_uri_source_installer_detail_new:
+ * @protocol: the URI protocol the missing source needs to implement,
+ *            e.g. "http" or "mms"
+ *
+ * Returns an opaque string containing all the details about the missing
+ * element to be passed to an external installer called via
+ * gst_install_plugins_async() or gst_install_plugins_sync().
+ * 
+ * This function is mainly for applications that call external plugin
+ * installation mechanisms using one of the two above-mentioned functions in
+ * the case where the application knows exactly what kind of plugin it is
+ * missing.
+ *
+ * Returns: a newly-allocated detail string, or NULL on error. Free string
+ *          with g_free() when not needed any longer.
+ *
+ * Since: 0.10.15
+ */
+gchar *
+gst_missing_uri_source_installer_detail_new (const gchar * protocol)
+{
+  gchar *desc;
+
+  g_return_val_if_fail (protocol != NULL, NULL);
+
+  desc = gst_pb_utils_get_source_description (protocol);
+  return gst_installer_detail_new (desc, "urisource", protocol);
+}
+
+/**
+ * gst_missing_uri_sink_installer_detail_new:
+ * @protocol: the URI protocol the missing source needs to implement,
+ *            e.g. "http" or "mms"
+ *
+ * Returns an opaque string containing all the details about the missing
+ * element to be passed to an external installer called via
+ * gst_install_plugins_async() or gst_install_plugins_sync().
+ * 
+ * This function is mainly for applications that call external plugin
+ * installation mechanisms using one of the two above-mentioned functions in
+ * the case where the application knows exactly what kind of plugin it is
+ * missing.
+ *
+ * Returns: a newly-allocated detail string, or NULL on error. Free string
+ *          with g_free() when not needed any longer.
+ *
+ * Since: 0.10.15
+ */
+gchar *
+gst_missing_uri_sink_installer_detail_new (const gchar * protocol)
+{
+  gchar *desc;
+
+  g_return_val_if_fail (protocol != NULL, NULL);
+
+  desc = gst_pb_utils_get_sink_description (protocol);
+  return gst_installer_detail_new (desc, "urisink", protocol);
+}
+
+/**
+ * gst_missing_element_installer_detail_new:
+ * @factory_name: the name of the missing element (element factory),
+ *            e.g. "videoscale" or "cdparanoiasrc"
+ *
+ * Returns an opaque string containing all the details about the missing
+ * element to be passed to an external installer called via
+ * gst_install_plugins_async() or gst_install_plugins_sync().
+ * 
+ * This function is mainly for applications that call external plugin
+ * installation mechanisms using one of the two above-mentioned functions in
+ * the case where the application knows exactly what kind of plugin it is
+ * missing.
+ *
+ * Returns: a newly-allocated detail string, or NULL on error. Free string
+ *          with g_free() when not needed any longer.
+ *
+ * Since: 0.10.15
+ */
+gchar *
+gst_missing_element_installer_detail_new (const gchar * factory_name)
+{
+  gchar *desc;
+
+  g_return_val_if_fail (factory_name != NULL, NULL);
+
+  desc = gst_pb_utils_get_element_description (factory_name);
+  return gst_installer_detail_new (desc, "element", factory_name);
+}
+
+/**
+ * gst_missing_decoder_installer_detail_new:
+ * @decode_caps: the (fixed) caps for which a decoder element is needed
+ *
+ * Returns an opaque string containing all the details about the missing
+ * element to be passed to an external installer called via
+ * gst_install_plugins_async() or gst_install_plugins_sync().
+ * 
+ * This function is mainly for applications that call external plugin
+ * installation mechanisms using one of the two above-mentioned functions in
+ * the case where the application knows exactly what kind of plugin it is
+ * missing.
+ *
+ * Returns: a newly-allocated detail string, or NULL on error. Free string
+ *          with g_free() when not needed any longer.
+ *
+ * Since: 0.10.15
+ */
+gchar *
+gst_missing_decoder_installer_detail_new (const GstCaps * decode_caps)
+{
+  GstCaps *caps;
+  gchar *detail_str, *caps_str, *desc;
+
+  g_return_val_if_fail (decode_caps != NULL, NULL);
+  g_return_val_if_fail (GST_IS_CAPS (decode_caps), NULL);
+  g_return_val_if_fail (!gst_caps_is_any (decode_caps), NULL);
+  g_return_val_if_fail (!gst_caps_is_empty (decode_caps), NULL);
+  g_return_val_if_fail (gst_caps_is_fixed (decode_caps), NULL);
+
+  desc = gst_pb_utils_get_decoder_description (decode_caps);
+  caps = copy_and_clean_caps (decode_caps);
+  caps_str = gst_caps_to_string (caps);
+  detail_str = gst_installer_detail_new (desc, "decoder", caps_str);
+  g_free (caps_str);
+  gst_caps_unref (caps);
+
+  return detail_str;
+}
+
+/**
+ * gst_missing_encoder_installer_detail_new:
+ * @encode_caps: the (fixed) caps for which an encoder element is needed
+ *
+ * Returns an opaque string containing all the details about the missing
+ * element to be passed to an external installer called via
+ * gst_install_plugins_async() or gst_install_plugins_sync().
+ * 
+ * This function is mainly for applications that call external plugin
+ * installation mechanisms using one of the two above-mentioned functions in
+ * the case where the application knows exactly what kind of plugin it is
+ * missing.
+ *
+ * Returns: a newly-allocated detail string, or NULL on error. Free string
+ *          with g_free() when not needed any longer.
+ *
+ * Since: 0.10.15
+ */
+gchar *
+gst_missing_encoder_installer_detail_new (const GstCaps * encode_caps)
+{
+  GstCaps *caps;
+  gchar *detail_str, *caps_str, *desc;
+
+  g_return_val_if_fail (encode_caps != NULL, NULL);
+  g_return_val_if_fail (GST_IS_CAPS (encode_caps), NULL);
+  g_return_val_if_fail (!gst_caps_is_any (encode_caps), NULL);
+  g_return_val_if_fail (!gst_caps_is_empty (encode_caps), NULL);
+  g_return_val_if_fail (gst_caps_is_fixed (encode_caps), NULL);
+
+  desc = gst_pb_utils_get_encoder_description (encode_caps);
+  caps = copy_and_clean_caps (encode_caps);
+  caps_str = gst_caps_to_string (caps);
+  detail_str = gst_installer_detail_new (desc, "encoder", caps_str);
+  g_free (caps_str);
+  gst_caps_unref (caps);
+
+  return detail_str;
+}
index e875b32..508304e 100644 (file)
@@ -45,7 +45,7 @@ GstMessage * gst_missing_encoder_message_new    (GstElement    * element,
                                                  const GstCaps * encode_caps);
 
 /*
- * functions for use by the application when dealing with missing-plugin messages
+ * functions for use by applications when dealing with missing-plugin messages
  */
 
 gchar       * gst_missing_plugin_message_get_installer_detail (GstMessage * msg);
@@ -53,7 +53,24 @@ gchar       * gst_missing_plugin_message_get_installer_detail (GstMessage * msg)
 gchar       * gst_missing_plugin_message_get_description (GstMessage * msg);
 
 gboolean      gst_is_missing_plugin_message (GstMessage * msg);
-   
+
+
+/*
+ * functions for use by applications that know exactly what plugins they are
+ * missing and want to request them directly rather than just react to
+ * missing-plugin messages posted by elements such as playbin or decodebin
+ */
+
+gchar * gst_missing_uri_source_installer_detail_new (const gchar * protocol);
+
+gchar * gst_missing_uri_sink_installer_detail_new (const gchar * protocol);
+
+gchar * gst_missing_element_installer_detail_new (const gchar * factory_name);
+
+gchar * gst_missing_decoder_installer_detail_new (const GstCaps * decode_caps);
+
+gchar * gst_missing_encoder_installer_detail_new (const GstCaps * encode_caps);
+
 G_END_DECLS
 
 #endif /* __GST_PB_UTILS_MISSING_PLUGINS_H__ */
index 3ae6270..368bf33 100644 (file)
@@ -72,7 +72,8 @@ GST_START_TEST (test_pb_utils_post_missing_messages)
   bus = gst_element_get_bus (pipeline);
 
   /* first, test common assertion failure cases */
-  ASSERT_CRITICAL (msg = gst_missing_uri_source_message_new (NULL, "http"););
+  ASSERT_CRITICAL (msg = gst_missing_uri_source_message_new (NULL, "http");
+      );
   ASSERT_CRITICAL (gst_missing_uri_source_message_new (pipeline, NULL));
 
   ASSERT_CRITICAL (gst_missing_uri_sink_message_new (NULL, "http"));
@@ -540,14 +541,11 @@ GST_START_TEST (test_pb_utils_install_plugins)
 
   ctx = gst_install_plugins_context_new ();
 
-  ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx);
-      );
+  ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx););
   ASSERT_CRITICAL (ret =
-      gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker);
-      );
+      gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker););
   ASSERT_CRITICAL (ret =
-      gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker);
-      );
+      gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker););
 
   /* make sure the functions return the right error code if the helper does
    * not exist */
@@ -591,6 +589,98 @@ GST_START_TEST (test_pb_utils_install_plugins)
 
 GST_END_TEST;
 
+GST_START_TEST (test_pb_utils_installer_details)
+{
+  GstMessage *msg;
+  GstElement *el;
+  GstCaps *caps;
+  gchar *detail1, *detail2;
+
+  el = gst_pipeline_new ("dummy-element");
+
+  /* uri source */
+  detail1 = gst_missing_uri_source_installer_detail_new ("http");
+  fail_unless (detail1 != NULL);
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_suffix (detail1, "|urisource-http"));
+  msg = gst_missing_uri_source_message_new (el, "http");
+  fail_unless (msg != NULL);
+  detail2 = gst_missing_plugin_message_get_installer_detail (msg);
+  fail_unless (detail2 != NULL);
+  gst_message_unref (msg);
+  fail_unless_equals_string (detail1, detail2);
+  g_free (detail1);
+  g_free (detail2);
+
+  /* uri sink */
+  detail1 = gst_missing_uri_sink_installer_detail_new ("http");
+  fail_unless (detail1 != NULL);
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_suffix (detail1, "|urisink-http"));
+  msg = gst_missing_uri_sink_message_new (el, "http");
+  fail_unless (msg != NULL);
+  detail2 = gst_missing_plugin_message_get_installer_detail (msg);
+  fail_unless (detail2 != NULL);
+  gst_message_unref (msg);
+  fail_unless_equals_string (detail1, detail2);
+  g_free (detail1);
+  g_free (detail2);
+
+  /* element */
+  detail1 = gst_missing_element_installer_detail_new ("deinterlace");
+  fail_unless (detail1 != NULL);
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_suffix (detail1, "|element-deinterlace"));
+  msg = gst_missing_element_message_new (el, "deinterlace");
+  fail_unless (msg != NULL);
+  detail2 = gst_missing_plugin_message_get_installer_detail (msg);
+  fail_unless (detail2 != NULL);
+  gst_message_unref (msg);
+  fail_unless_equals_string (detail1, detail2);
+  g_free (detail1);
+  g_free (detail2);
+
+  /* decoder */
+  caps = gst_caps_new_simple ("audio/x-spiffy", "spiffyversion", G_TYPE_INT,
+      2, "channels", G_TYPE_INT, 6, NULL);
+  detail1 = gst_missing_decoder_installer_detail_new (caps);
+  fail_unless (detail1 != NULL);
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_suffix (detail1,
+          "|decoder-audio/x-spiffy, spiffyversion=(int)2"));
+  msg = gst_missing_decoder_message_new (el, caps);
+  fail_unless (msg != NULL);
+  detail2 = gst_missing_plugin_message_get_installer_detail (msg);
+  fail_unless (detail2 != NULL);
+  gst_message_unref (msg);
+  gst_caps_unref (caps);
+  fail_unless_equals_string (detail1, detail2);
+  g_free (detail1);
+  g_free (detail2);
+
+  /* encoder */
+  caps = gst_caps_new_simple ("audio/x-spiffy", "spiffyversion", G_TYPE_INT,
+      2, "channels", G_TYPE_INT, 6, NULL);
+  detail1 = gst_missing_encoder_installer_detail_new (caps);
+  fail_unless (g_str_has_prefix (detail1, "gstreamer|0.10|"));
+  fail_unless (g_str_has_suffix (detail1,
+          "|encoder-audio/x-spiffy, spiffyversion=(int)2"));
+  fail_unless (detail1 != NULL);
+  msg = gst_missing_encoder_message_new (el, caps);
+  fail_unless (msg != NULL);
+  detail2 = gst_missing_plugin_message_get_installer_detail (msg);
+  fail_unless (detail2 != NULL);
+  gst_message_unref (msg);
+  gst_caps_unref (caps);
+  fail_unless_equals_string (detail1, detail2);
+  g_free (detail1);
+  g_free (detail2);
+
+  gst_object_unref (el);
+}
+
+GST_END_TEST;
+
 static Suite *
 libgstpbutils_suite (void)
 {
@@ -603,6 +693,7 @@ libgstpbutils_suite (void)
   tcase_add_test (tc_chain, test_pb_utils_taglist_add_codec_info);
   tcase_add_test (tc_chain, test_pb_utils_get_codec_description);
   tcase_add_test (tc_chain, test_pb_utils_install_plugins);
+  tcase_add_test (tc_chain, test_pb_utils_installer_details);
   return s;
 }