API: add gst_missing_*_installer_detail_new() convenience API so that applications that know exactly what they're mis...

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.
This commit is contained in:
Tim-Philipp Müller 2007-08-28 14:23:55 +00:00
parent 973bbf88af
commit f344ec6b8a
5 changed files with 337 additions and 9 deletions

View file

@ -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):

View 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>

View 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;
}

View 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__ */

View 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;
}