mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gst-libs/gst/utils/: API: add API for applications to initiate installation of missing plugins, ie. gst_install_plugi...
Original commit message from CVS: * gst-libs/gst/utils/Makefile.am: * gst-libs/gst/utils/base-utils.h: * gst-libs/gst/utils/install-plugins.c: (gst_install_plugins_context_set_xid), (gst_install_plugins_context_new), (gst_install_plugins_context_free), (gst_install_plugins_get_helper), (gst_install_plugins_spawn_child), (gst_install_plugins_return_from_status), (gst_install_plugins_installer_exited), (gst_install_plugins_async), (gst_install_plugins_sync), (gst_install_plugins_return_get_name), (gst_install_plugins_installation_in_progress): * gst-libs/gst/utils/install-plugins.h: API: add API for applications to initiate installation of missing plugins, ie. gst_install_plugins_async() primarily. Based on libgimme-codec by Ryan Lortie. * configure.ac: Add --with-install-plugins-helper configure option so distros can specify the path of the helper script or program to call when plugin installation is requested (distros: please do any argument munging in this helper script instead of patching GStreamer to pass arguments differently to another program directly). * docs/libs/gst-plugins-base-libs-docs.sgml: * docs/libs/gst-plugins-base-libs-sections.txt: Build and document new API. * tests/check/libs/utils.c: (result_cb), (test_base_utils_install_plugins_do_callout), (GST_START_TEST), (libgstbaseutils_suite): Some simple checks for the new API.
This commit is contained in:
parent
7439949980
commit
17a02da2fd
14 changed files with 1445 additions and 4 deletions
36
ChangeLog
36
ChangeLog
|
@ -1,3 +1,39 @@
|
|||
2007-02-02 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst-libs/gst/utils/Makefile.am:
|
||||
* gst-libs/gst/utils/base-utils.h:
|
||||
* gst-libs/gst/utils/install-plugins.c:
|
||||
(gst_install_plugins_context_set_xid),
|
||||
(gst_install_plugins_context_new),
|
||||
(gst_install_plugins_context_free),
|
||||
(gst_install_plugins_get_helper),
|
||||
(gst_install_plugins_spawn_child),
|
||||
(gst_install_plugins_return_from_status),
|
||||
(gst_install_plugins_installer_exited),
|
||||
(gst_install_plugins_async), (gst_install_plugins_sync),
|
||||
(gst_install_plugins_return_get_name),
|
||||
(gst_install_plugins_installation_in_progress):
|
||||
* gst-libs/gst/utils/install-plugins.h:
|
||||
API: add API for applications to initiate installation of missing
|
||||
plugins, ie. gst_install_plugins_async() primarily.
|
||||
Based on libgimme-codec by Ryan Lortie.
|
||||
|
||||
* configure.ac:
|
||||
Add --with-install-plugins-helper configure option so distros can specify
|
||||
the path of the helper script or program to call when plugin installation
|
||||
is requested (distros: please do any argument munging in this helper
|
||||
script instead of patching GStreamer to pass arguments differently
|
||||
to another program directly).
|
||||
|
||||
* docs/libs/gst-plugins-base-libs-docs.sgml:
|
||||
* docs/libs/gst-plugins-base-libs-sections.txt:
|
||||
Build and document new API.
|
||||
|
||||
* tests/check/libs/utils.c: (result_cb),
|
||||
(test_base_utils_install_plugins_do_callout), (GST_START_TEST),
|
||||
(libgstbaseutils_suite):
|
||||
Some simple checks for the new API.
|
||||
|
||||
2007-02-02 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* tests/check/elements/audioconvert.c: (test_float_conversion):
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -81,6 +81,28 @@ GST_ARG_WITH_PKG_CONFIG_PATH
|
|||
GST_ARG_WITH_PACKAGE_NAME
|
||||
GST_ARG_WITH_PACKAGE_ORIGIN
|
||||
|
||||
dnl let distro override plugin install helper path
|
||||
AC_ARG_WITH(install-plugins-helper,
|
||||
AC_HELP_STRING([--with-install-plugins-helper],
|
||||
[specify path of helper script to call to install plugins]),
|
||||
[
|
||||
case "${withval}" in
|
||||
yes) AC_MSG_ERROR(bad value ${withval} for --with-install-plugins-helper) ;;
|
||||
no) AC_MSG_ERROR(bad value ${withval} for --with-install-plugins-helper) ;;
|
||||
*) GST_INSTALL_PLUGINS_HELPER="${withval}" ;;
|
||||
esac
|
||||
],
|
||||
[
|
||||
dnl Default value
|
||||
AS_AC_EXPAND(GST_INSTALL_PLUGINS_HELPER,${libexecdir}/gst-install-plugins-helper)
|
||||
]
|
||||
)
|
||||
AC_MSG_NOTICE(Using $GST_INSTALL_PLUGINS_HELPER as plugin install helper)
|
||||
AC_DEFINE_UNQUOTED(GST_INSTALL_PLUGINS_HELPER, "$GST_INSTALL_PLUGINS_HELPER",
|
||||
[plugin install helper script])
|
||||
AC_SUBST(GST_INSTALL_PLUGINS_HELPER)
|
||||
|
||||
|
||||
dnl these are all the gst plug-ins, compilable without additional libs
|
||||
GST_PLUGINS_ALL="\
|
||||
adder \
|
||||
|
@ -182,8 +204,8 @@ AC_CHECK_HEADERS([sys/socket.h],
|
|||
HAVE_SYS_SOCKET_H="yes", HAVE_SYS_SOCKET_H="no")
|
||||
AM_CONDITIONAL(HAVE_SYS_SOCKET_H, test "x$HAVE_SYS_SOCKET_H" = "xyes")
|
||||
|
||||
dnl used in gst-libs/gst/utils
|
||||
AC_CHECK_HEADERS([process.h])
|
||||
dnl used in gst-libs/gst/utils and associated unit test
|
||||
AC_CHECK_HEADERS([process.h sys/types.h sys/wait.h sys/stat.h])
|
||||
|
||||
dnl ffmpegcolorspace includes _stdint.h
|
||||
dnl also, Windows does not have long long
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
<!ENTITY GstBaseUtils SYSTEM "xml/gstbaseutils.xml">
|
||||
<!ENTITY GstBaseUtilsDescriptions SYSTEM "xml/gstbaseutilsdescriptions.xml">
|
||||
<!ENTITY GstBaseUtilsMissingPlugins SYSTEM "xml/gstbaseutilsmissingplugins.xml">
|
||||
<!ENTITY GstBaseUtilsInstallPlugins SYSTEM "xml/gstbaseutilsinstallplugins.xml">
|
||||
<!-- video -->
|
||||
<!ENTITY GstVideo SYSTEM "xml/gstvideo.xml">
|
||||
<!ENTITY GstVideoFilter SYSTEM "xml/gstvideofilter.xml">
|
||||
|
@ -188,6 +189,7 @@
|
|||
&GstBaseUtils;
|
||||
&GstBaseUtilsDescriptions;
|
||||
&GstBaseUtilsMissingPlugins;
|
||||
&GstBaseUtilsInstallPlugins;
|
||||
</chapter>
|
||||
|
||||
<chapter id="gstreamer-video">
|
||||
|
|
|
@ -941,6 +941,23 @@ gst_missing_uri_sink_message_new
|
|||
gst_missing_element_message_new
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstbaseutilsinstallplugins</FILE>
|
||||
<INCLUDE>gst/utils/install-plugins.h</INCLUDE>
|
||||
<SUBSECTION>
|
||||
GstInstallPluginsReturn
|
||||
GstInstallPluginsResultFunc
|
||||
gst_install_plugins_async
|
||||
gst_install_plugins_sync
|
||||
gst_install_plugins_return_get_name
|
||||
gst_install_plugins_installation_in_progress
|
||||
<SUBSECTION>
|
||||
GstInstallPluginsContext
|
||||
gst_install_plugins_context_new
|
||||
gst_install_plugins_context_free
|
||||
gst_install_plugins_context_set_xid
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstbaseutilsdescriptions</FILE>
|
||||
<INCLUDE>gst/utils/descriptions.h</INCLUDE>
|
||||
|
|
|
@ -5,6 +5,8 @@ libgstbaseutils_@GST_MAJORMINOR@_la_SOURCES = \
|
|||
base-utils.h \
|
||||
descriptions.c \
|
||||
descriptions.h \
|
||||
install-plugins.c \
|
||||
install-plugins.h \
|
||||
missing-plugins.c \
|
||||
missing-plugins.h
|
||||
|
||||
|
@ -12,6 +14,7 @@ libgstbaseutils_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORM
|
|||
libgstbaseutils_@GST_MAJORMINOR@include_HEADERS = \
|
||||
base-utils.h \
|
||||
descriptions.h \
|
||||
install-plugins.h \
|
||||
missing-plugins.h
|
||||
|
||||
libgstbaseutils_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS)
|
||||
|
|
388
gst-libs/gst/pbutils/install-plugins.c
Normal file
388
gst-libs/gst/pbutils/install-plugins.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/* GStreamer base utils library plugin install support for applications
|
||||
* Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
|
||||
* Copyright (C) 2006 Ryan Lortie <desrt desrt ca>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "install-plugins.h"
|
||||
|
||||
#include <gst/gstinfo.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
/* best effort to make things compile and possibly even work on win32 */
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(status) ((((guint)(status)) & 0xff00) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
# define WIFEXITED(status) ((((guint)(status)) & 0x7f) == 0)
|
||||
#endif
|
||||
|
||||
static gboolean install_in_progress; /* FALSE */
|
||||
|
||||
/* private struct */
|
||||
struct _GstInstallPluginsContext
|
||||
{
|
||||
guint xid;
|
||||
};
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_set_xid:
|
||||
* @ctx: a #GstInstallPluginsContext
|
||||
* @xid: the XWindow ID (XID) of the top-level application
|
||||
*
|
||||
* This function is for X11-based applications (such as most Gtk/Qt
|
||||
* applications on linux/unix) only. You can use it to tell the external
|
||||
* the XID of your main application window, so the installer can make its
|
||||
* own window transient to your application windonw during the installation.
|
||||
*
|
||||
* If set, the XID will be passed to the installer via a --transient-for=XID
|
||||
* command line option.
|
||||
*
|
||||
* Gtk+/Gnome application should be able to obtain the XID of the top-level
|
||||
* window like this:
|
||||
* <programlisting>
|
||||
* ##include <gtk/gtk.h>
|
||||
* ##ifdef GDK_WINDOWING_X11
|
||||
* ##include <gdk/gdkx.h>
|
||||
* ##endif
|
||||
* ...
|
||||
* ##ifdef GDK_WINDOWING_X11
|
||||
* xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (application_window)->window);
|
||||
* ##endif
|
||||
* ...
|
||||
* </programlisting>
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
void
|
||||
gst_install_plugins_context_set_xid (GstInstallPluginsContext * ctx, guint xid)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
|
||||
ctx->xid = xid;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_new:
|
||||
*
|
||||
* Creates a new #GstInstallPluginsContext.
|
||||
*
|
||||
* Returns: a new #GstInstallPluginsContext. Free with
|
||||
* gst_install_plugins_context_free() when no longer needed
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
GstInstallPluginsContext *
|
||||
gst_install_plugins_context_new (void)
|
||||
{
|
||||
return g_new0 (GstInstallPluginsContext, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_free:
|
||||
* @ctx: a #GstInstallPluginsContext
|
||||
*
|
||||
* Frees a #GstInstallPluginsContext.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
void
|
||||
gst_install_plugins_context_free (GstInstallPluginsContext * ctx)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
|
||||
g_free (ctx);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gst_install_plugins_get_helper (void)
|
||||
{
|
||||
const gchar *helper;
|
||||
|
||||
helper = g_getenv ("GST_INSTALL_PLUGINS_HELPER");
|
||||
if (helper == NULL)
|
||||
helper = GST_INSTALL_PLUGINS_HELPER;
|
||||
|
||||
GST_LOG ("Using plugin install helper '%s'", helper);
|
||||
return helper;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_install_plugins_spawn_child (gchar ** details,
|
||||
GstInstallPluginsContext * ctx, GPid * child_pid, gint * exit_status)
|
||||
{
|
||||
GPtrArray *arr;
|
||||
gboolean ret;
|
||||
GError *err = NULL;
|
||||
gchar **argv, xid_str[64] = { 0, };
|
||||
|
||||
arr = g_ptr_array_new ();
|
||||
|
||||
/* argv[0] = helper path */
|
||||
g_ptr_array_add (arr, (gchar *) gst_install_plugins_get_helper ());
|
||||
|
||||
/* add any additional command line args from the context */
|
||||
if (ctx != NULL && ctx->xid != 0) {
|
||||
g_snprintf (xid_str, sizeof (xid_str), "--transient-for=%u", ctx->xid);
|
||||
g_ptr_array_add (arr, xid_str);
|
||||
}
|
||||
|
||||
/* finally, add the detail strings */
|
||||
while (details != NULL && details[0] != NULL) {
|
||||
g_ptr_array_add (arr, details[0]);
|
||||
++details;
|
||||
}
|
||||
|
||||
/* and NULL-terminate */
|
||||
g_ptr_array_add (arr, NULL);
|
||||
|
||||
argv = (gchar **) arr->pdata;
|
||||
|
||||
if (child_pid == NULL && exit_status != NULL) {
|
||||
install_in_progress = TRUE;
|
||||
ret = g_spawn_sync (NULL, argv, NULL, (GSpawnFlags) 0, NULL, NULL,
|
||||
NULL, NULL, exit_status, &err);
|
||||
install_in_progress = FALSE;
|
||||
} else if (child_pid != NULL && exit_status == NULL) {
|
||||
install_in_progress = TRUE;
|
||||
ret = g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL,
|
||||
NULL, child_pid, &err);
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
GST_WARNING ("Error spawning plugin install helper: %s", err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
|
||||
g_ptr_array_free (arr, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstInstallPluginsReturn
|
||||
gst_install_plugins_return_from_status (gint status)
|
||||
{
|
||||
GstInstallPluginsReturn ret;
|
||||
|
||||
/* did we exit cleanly? */
|
||||
if (!WIFEXITED (status)) {
|
||||
ret = GST_INSTALL_PLUGINS_CRASHED;
|
||||
} else {
|
||||
ret = (GstInstallPluginsReturn) WEXITSTATUS (status);
|
||||
|
||||
/* did the helper return an invalid status code? */
|
||||
if ((ret < 0 || ret >= GST_INSTALL_PLUGINS_STARTED_OK) &&
|
||||
ret != GST_INSTALL_PLUGINS_INTERNAL_FAILURE) {
|
||||
ret = GST_INSTALL_PLUGINS_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
GST_LOG ("plugin installer exited with status 0x%04x = %s", status,
|
||||
gst_install_plugins_return_get_name (ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstInstallPluginsResultFunc func;
|
||||
gpointer user_data;
|
||||
} GstInstallPluginsAsyncHelper;
|
||||
|
||||
static void
|
||||
gst_install_plugins_installer_exited (GPid pid, gint status, gpointer data)
|
||||
{
|
||||
GstInstallPluginsAsyncHelper *helper;
|
||||
GstInstallPluginsReturn ret;
|
||||
|
||||
install_in_progress = FALSE;
|
||||
|
||||
helper = (GstInstallPluginsAsyncHelper *) data;
|
||||
ret = gst_install_plugins_return_from_status (status);
|
||||
|
||||
GST_LOG ("calling plugin install result function %p", helper->func);
|
||||
helper->func (ret, helper->user_data);
|
||||
|
||||
g_free (helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_async:
|
||||
* @details: NULL-terminated array of installer string details (see below)
|
||||
* @ctx: a #GstInstallPluginsContext, or NULL
|
||||
* @func: the function to call when the installer program returns
|
||||
* @user_data: the user data to pass to @func when called, or NULL
|
||||
*
|
||||
* Requests plugin installation without blocking. Once the plugins have been
|
||||
* installed or installation has failed, @func will be called with the result
|
||||
* of the installation and your provided @user_data pointer.
|
||||
*
|
||||
* This function requires a running GLib/Gtk main loop. If you are not
|
||||
* running a GLib/Gtk main loop, make sure to regularly call
|
||||
* g_main_context_iteration(NULL,FALSE).
|
||||
*
|
||||
* The installer strings that make up @detail are typically obtained by
|
||||
* calling gst_missing_plugin_message_get_installer_detail() on missing-plugin
|
||||
* messages that have been caught on a pipeline's bus or created by the
|
||||
* application via the provided API, such as gst_missing_element_message_new().
|
||||
*
|
||||
* Returns: result code whether an external installer could be started
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
|
||||
GstInstallPluginsReturn
|
||||
gst_install_plugins_async (gchar ** details, GstInstallPluginsContext * ctx,
|
||||
GstInstallPluginsResultFunc func, gpointer user_data)
|
||||
{
|
||||
GstInstallPluginsAsyncHelper *helper;
|
||||
GPid pid;
|
||||
|
||||
g_return_val_if_fail (details != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
g_return_val_if_fail (func != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
|
||||
if (install_in_progress)
|
||||
return GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS;
|
||||
|
||||
/* if we can't access our helper, don't bother */
|
||||
if (!g_file_test (gst_install_plugins_get_helper (),
|
||||
G_FILE_TEST_IS_EXECUTABLE))
|
||||
return GST_INSTALL_PLUGINS_HELPER_MISSING;
|
||||
|
||||
if (!gst_install_plugins_spawn_child (details, ctx, &pid, NULL))
|
||||
return GST_INSTALL_PLUGINS_INTERNAL_FAILURE;
|
||||
|
||||
helper = g_new (GstInstallPluginsAsyncHelper, 1);
|
||||
helper->func = func;
|
||||
helper->user_data = user_data;
|
||||
|
||||
g_child_watch_add (pid, gst_install_plugins_installer_exited, helper);
|
||||
|
||||
return GST_INSTALL_PLUGINS_STARTED_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_sync:
|
||||
* @details: NULL-terminated array of installer string details
|
||||
* @ctx: a #GstInstallPluginsContext, or NULL
|
||||
*
|
||||
* Requests plugin installation and block until the plugins have been
|
||||
* installed or installation has failed.
|
||||
*
|
||||
* This function should almost never be used, it only exists for cases where
|
||||
* a non-GLib main loop is running and the user wants to run it in a separate
|
||||
* thread and marshal the result back asynchronously into the main thread
|
||||
* using the other non-GLib main loop. You should almost always use
|
||||
* gst_install_plugins_async() instead of this function.
|
||||
*
|
||||
* Returns: the result of the installation.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
GstInstallPluginsReturn
|
||||
gst_install_plugins_sync (gchar ** details, GstInstallPluginsContext * ctx)
|
||||
{
|
||||
gint status;
|
||||
|
||||
g_return_val_if_fail (details != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
|
||||
if (install_in_progress)
|
||||
return GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS;
|
||||
|
||||
/* if we can't access our helper, don't bother */
|
||||
if (!g_file_test (gst_install_plugins_get_helper (),
|
||||
G_FILE_TEST_IS_EXECUTABLE))
|
||||
return GST_INSTALL_PLUGINS_HELPER_MISSING;
|
||||
|
||||
if (!gst_install_plugins_spawn_child (details, ctx, NULL, &status))
|
||||
return GST_INSTALL_PLUGINS_INTERNAL_FAILURE;
|
||||
|
||||
return gst_install_plugins_return_from_status (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_return_get_name:
|
||||
* @ret: the return status code
|
||||
*
|
||||
* Convenience function to return the descriptive string associated
|
||||
* with a status code. This function returns English strings and
|
||||
* should not be used for user messages. It is here only to assist
|
||||
* in debugging.
|
||||
*
|
||||
* Returns: a descriptive string for the status code in @ret
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
const gchar *
|
||||
gst_install_plugins_return_get_name (GstInstallPluginsReturn ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case GST_INSTALL_PLUGINS_SUCCESS:
|
||||
return "success";
|
||||
case GST_INSTALL_PLUGINS_NOT_FOUND:
|
||||
return "not-found";
|
||||
case GST_INSTALL_PLUGINS_ERROR:
|
||||
return "install-error";
|
||||
case GST_INSTALL_PLUGINS_CRASHED:
|
||||
return "installer-exit-unclean";
|
||||
case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
|
||||
return "partial-success";
|
||||
case GST_INSTALL_PLUGINS_USER_ABORT:
|
||||
return "user-abort";
|
||||
case GST_INSTALL_PLUGINS_STARTED_OK:
|
||||
return "started-ok";
|
||||
case GST_INSTALL_PLUGINS_INTERNAL_FAILURE:
|
||||
return "internal-failure";
|
||||
case GST_INSTALL_PLUGINS_HELPER_MISSING:
|
||||
return "helper-missing";
|
||||
case GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS:
|
||||
return "install-in-progress";
|
||||
case GST_INSTALL_PLUGINS_INVALID:
|
||||
return "invalid";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "(UNKNOWN)";
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_installation_in_progress:
|
||||
*
|
||||
* Checks whether plugin installation (initiated by this application only)
|
||||
* is currently in progress.
|
||||
*
|
||||
* Returns: TRUE if plugin installation is in progress, otherwise FALSE
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
gboolean
|
||||
gst_install_plugins_installation_in_progress (void)
|
||||
{
|
||||
return install_in_progress;
|
||||
}
|
137
gst-libs/gst/pbutils/install-plugins.h
Normal file
137
gst-libs/gst/pbutils/install-plugins.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* GStreamer base utils library plugin install support for applications
|
||||
* Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
|
||||
* Copyright (C) 2006 Ryan Lortie <desrt desrt ca>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_BASE_UTILS_INSTALL_PLUGINS_H__
|
||||
#define __GST_BASE_UTILS_INSTALL_PLUGINS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* functions for use by applications to initiate installation of missing plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* GstInstallPluginsReturn:
|
||||
* @GST_INSTALL_PLUGINS_SUCCESS: all of the requested plugins could be
|
||||
* installed
|
||||
* @GST_INSTALL_PLUGINS_NOT_FOUND: no appropriate installation candidate for
|
||||
* any of the requested plugins could be found. Only return this if nothing
|
||||
* has been installed. Return #GST_INSTALL_PLUGINS_PARTIAL_SUCCESS if
|
||||
* some (but not all) of the requested plugins could be installed.
|
||||
* @GST_INSTALL_PLUGINS_ERROR: an error occured during the installation. If
|
||||
* this happens, the user has already seen an error message and another
|
||||
* one should not be displayed
|
||||
* @GST_INSTALL_PLUGINS_CRASHED: the installer had an unclean exit code
|
||||
* (ie. death by signal)
|
||||
* @GST_INSTALL_PLUGINS_PARTIAL_SUCCESS: some of the requested plugins could
|
||||
* be installed, but not all
|
||||
* @GST_INSTALL_PLUGINS_USER_ABORT: the user has aborted the installation
|
||||
* @GST_INSTALL_PLUGINS_INVALID: the helper returned an invalid status code
|
||||
* @GST_INSTALL_PLUGINS_STARTED_OK: returned by gst_install_plugins_async() to
|
||||
* indicate that everything went fine so far and the provided callback
|
||||
* will be called with the result of the installation later
|
||||
* @GST_INSTALL_PLUGINS_INTERNAL_FAILURE: some internal failure has
|
||||
* occured when trying to start the installer
|
||||
* @GST_INSTALL_PLUGINS_HELPER_MISSING: the helper script to call the
|
||||
* actual installer is not installed
|
||||
* @GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS: a previously-started plugin
|
||||
* installation is still in progress, try again later
|
||||
*
|
||||
* Result codes returned by gst_install_plugins_async() and
|
||||
* gst_install_plugins_sync(), and also the result code passed to the
|
||||
* #GstInstallPluginsResultFunc specified with gst_install_plugin_async().
|
||||
*
|
||||
* These codes indicate success or failure of starting an external installer
|
||||
* program and to what extent the requested plugins could be installed.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef enum {
|
||||
/* Return codes from the installer. Returned by gst_install_plugins_sync(),
|
||||
* or passed as result code to your #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_SUCCESS = 0,
|
||||
GST_INSTALL_PLUGINS_NOT_FOUND = 1,
|
||||
GST_INSTALL_PLUGINS_ERROR = 2,
|
||||
GST_INSTALL_PLUGINS_PARTIAL_SUCCESS = 3,
|
||||
GST_INSTALL_PLUGINS_USER_ABORT = 4,
|
||||
|
||||
/* Returned by gst_install_plugins_sync(), or passed as result code to your
|
||||
* #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_CRASHED = 100,
|
||||
GST_INSTALL_PLUGINS_INVALID,
|
||||
|
||||
/* Return codes from starting the external helper, may be returned by both
|
||||
* gst_install_plugins_sync() and gst_install_plugins_async(), but should
|
||||
* never be seen by a #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_STARTED_OK = 200,
|
||||
GST_INSTALL_PLUGINS_INTERNAL_FAILURE,
|
||||
GST_INSTALL_PLUGINS_HELPER_MISSING,
|
||||
GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS
|
||||
} GstInstallPluginsReturn;
|
||||
|
||||
/**
|
||||
* GstInstallPluginsContext:
|
||||
*
|
||||
* Opaque context structure for the plugin installation. Use the provided
|
||||
* API to set details on it.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef struct _GstInstallPluginsContext GstInstallPluginsContext;
|
||||
|
||||
GstInstallPluginsContext * gst_install_plugins_context_new (void);
|
||||
|
||||
void gst_install_plugins_context_free (GstInstallPluginsContext * ctx);
|
||||
|
||||
void gst_install_plugins_context_set_xid (GstInstallPluginsContext * ctx,
|
||||
guint xid);
|
||||
|
||||
/**
|
||||
* GstInstallPluginsResultFunc:
|
||||
* @result: whether the installation of the requested plugins succeeded or not
|
||||
* @user_data: the user data passed to gst_install_plugins_async()
|
||||
*
|
||||
* The prototype of the callback function that will be called once the
|
||||
* external plugin installer program has returned. You only need to provide
|
||||
* a callback function if you are using the asynchronous interface.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef void (*GstInstallPluginsResultFunc) (GstInstallPluginsReturn result,
|
||||
gpointer user_data);
|
||||
|
||||
GstInstallPluginsReturn gst_install_plugins_async (gchar ** details,
|
||||
GstInstallPluginsContext * ctx,
|
||||
GstInstallPluginsResultFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
GstInstallPluginsReturn gst_install_plugins_sync (gchar ** details,
|
||||
GstInstallPluginsContext * ctx);
|
||||
|
||||
const gchar * gst_install_plugins_return_get_name (GstInstallPluginsReturn ret);
|
||||
|
||||
gboolean gst_install_plugins_installation_in_progress (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_BASE_UTILS_INSTALL_PLUGINS_H__ */
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <gst/utils/descriptions.h>
|
||||
#include <gst/utils/missing-plugins.h>
|
||||
#include <gst/utils/install-plugins.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ libgstbaseutils_@GST_MAJORMINOR@_la_SOURCES = \
|
|||
base-utils.h \
|
||||
descriptions.c \
|
||||
descriptions.h \
|
||||
install-plugins.c \
|
||||
install-plugins.h \
|
||||
missing-plugins.c \
|
||||
missing-plugins.h
|
||||
|
||||
|
@ -12,6 +14,7 @@ libgstbaseutils_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORM
|
|||
libgstbaseutils_@GST_MAJORMINOR@include_HEADERS = \
|
||||
base-utils.h \
|
||||
descriptions.h \
|
||||
install-plugins.h \
|
||||
missing-plugins.h
|
||||
|
||||
libgstbaseutils_@GST_MAJORMINOR@_la_LIBADD = $(GST_LIBS)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <gst/utils/descriptions.h>
|
||||
#include <gst/utils/missing-plugins.h>
|
||||
#include <gst/utils/install-plugins.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
388
gst-libs/gst/utils/install-plugins.c
Normal file
388
gst-libs/gst/utils/install-plugins.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/* GStreamer base utils library plugin install support for applications
|
||||
* Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
|
||||
* Copyright (C) 2006 Ryan Lortie <desrt desrt ca>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "install-plugins.h"
|
||||
|
||||
#include <gst/gstinfo.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
/* best effort to make things compile and possibly even work on win32 */
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(status) ((((guint)(status)) & 0xff00) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
# define WIFEXITED(status) ((((guint)(status)) & 0x7f) == 0)
|
||||
#endif
|
||||
|
||||
static gboolean install_in_progress; /* FALSE */
|
||||
|
||||
/* private struct */
|
||||
struct _GstInstallPluginsContext
|
||||
{
|
||||
guint xid;
|
||||
};
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_set_xid:
|
||||
* @ctx: a #GstInstallPluginsContext
|
||||
* @xid: the XWindow ID (XID) of the top-level application
|
||||
*
|
||||
* This function is for X11-based applications (such as most Gtk/Qt
|
||||
* applications on linux/unix) only. You can use it to tell the external
|
||||
* the XID of your main application window, so the installer can make its
|
||||
* own window transient to your application windonw during the installation.
|
||||
*
|
||||
* If set, the XID will be passed to the installer via a --transient-for=XID
|
||||
* command line option.
|
||||
*
|
||||
* Gtk+/Gnome application should be able to obtain the XID of the top-level
|
||||
* window like this:
|
||||
* <programlisting>
|
||||
* ##include <gtk/gtk.h>
|
||||
* ##ifdef GDK_WINDOWING_X11
|
||||
* ##include <gdk/gdkx.h>
|
||||
* ##endif
|
||||
* ...
|
||||
* ##ifdef GDK_WINDOWING_X11
|
||||
* xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (application_window)->window);
|
||||
* ##endif
|
||||
* ...
|
||||
* </programlisting>
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
void
|
||||
gst_install_plugins_context_set_xid (GstInstallPluginsContext * ctx, guint xid)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
|
||||
ctx->xid = xid;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_new:
|
||||
*
|
||||
* Creates a new #GstInstallPluginsContext.
|
||||
*
|
||||
* Returns: a new #GstInstallPluginsContext. Free with
|
||||
* gst_install_plugins_context_free() when no longer needed
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
GstInstallPluginsContext *
|
||||
gst_install_plugins_context_new (void)
|
||||
{
|
||||
return g_new0 (GstInstallPluginsContext, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_context_free:
|
||||
* @ctx: a #GstInstallPluginsContext
|
||||
*
|
||||
* Frees a #GstInstallPluginsContext.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
void
|
||||
gst_install_plugins_context_free (GstInstallPluginsContext * ctx)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
|
||||
g_free (ctx);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gst_install_plugins_get_helper (void)
|
||||
{
|
||||
const gchar *helper;
|
||||
|
||||
helper = g_getenv ("GST_INSTALL_PLUGINS_HELPER");
|
||||
if (helper == NULL)
|
||||
helper = GST_INSTALL_PLUGINS_HELPER;
|
||||
|
||||
GST_LOG ("Using plugin install helper '%s'", helper);
|
||||
return helper;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_install_plugins_spawn_child (gchar ** details,
|
||||
GstInstallPluginsContext * ctx, GPid * child_pid, gint * exit_status)
|
||||
{
|
||||
GPtrArray *arr;
|
||||
gboolean ret;
|
||||
GError *err = NULL;
|
||||
gchar **argv, xid_str[64] = { 0, };
|
||||
|
||||
arr = g_ptr_array_new ();
|
||||
|
||||
/* argv[0] = helper path */
|
||||
g_ptr_array_add (arr, (gchar *) gst_install_plugins_get_helper ());
|
||||
|
||||
/* add any additional command line args from the context */
|
||||
if (ctx != NULL && ctx->xid != 0) {
|
||||
g_snprintf (xid_str, sizeof (xid_str), "--transient-for=%u", ctx->xid);
|
||||
g_ptr_array_add (arr, xid_str);
|
||||
}
|
||||
|
||||
/* finally, add the detail strings */
|
||||
while (details != NULL && details[0] != NULL) {
|
||||
g_ptr_array_add (arr, details[0]);
|
||||
++details;
|
||||
}
|
||||
|
||||
/* and NULL-terminate */
|
||||
g_ptr_array_add (arr, NULL);
|
||||
|
||||
argv = (gchar **) arr->pdata;
|
||||
|
||||
if (child_pid == NULL && exit_status != NULL) {
|
||||
install_in_progress = TRUE;
|
||||
ret = g_spawn_sync (NULL, argv, NULL, (GSpawnFlags) 0, NULL, NULL,
|
||||
NULL, NULL, exit_status, &err);
|
||||
install_in_progress = FALSE;
|
||||
} else if (child_pid != NULL && exit_status == NULL) {
|
||||
install_in_progress = TRUE;
|
||||
ret = g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL,
|
||||
NULL, child_pid, &err);
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
GST_WARNING ("Error spawning plugin install helper: %s", err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
|
||||
g_ptr_array_free (arr, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstInstallPluginsReturn
|
||||
gst_install_plugins_return_from_status (gint status)
|
||||
{
|
||||
GstInstallPluginsReturn ret;
|
||||
|
||||
/* did we exit cleanly? */
|
||||
if (!WIFEXITED (status)) {
|
||||
ret = GST_INSTALL_PLUGINS_CRASHED;
|
||||
} else {
|
||||
ret = (GstInstallPluginsReturn) WEXITSTATUS (status);
|
||||
|
||||
/* did the helper return an invalid status code? */
|
||||
if ((ret < 0 || ret >= GST_INSTALL_PLUGINS_STARTED_OK) &&
|
||||
ret != GST_INSTALL_PLUGINS_INTERNAL_FAILURE) {
|
||||
ret = GST_INSTALL_PLUGINS_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
GST_LOG ("plugin installer exited with status 0x%04x = %s", status,
|
||||
gst_install_plugins_return_get_name (ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstInstallPluginsResultFunc func;
|
||||
gpointer user_data;
|
||||
} GstInstallPluginsAsyncHelper;
|
||||
|
||||
static void
|
||||
gst_install_plugins_installer_exited (GPid pid, gint status, gpointer data)
|
||||
{
|
||||
GstInstallPluginsAsyncHelper *helper;
|
||||
GstInstallPluginsReturn ret;
|
||||
|
||||
install_in_progress = FALSE;
|
||||
|
||||
helper = (GstInstallPluginsAsyncHelper *) data;
|
||||
ret = gst_install_plugins_return_from_status (status);
|
||||
|
||||
GST_LOG ("calling plugin install result function %p", helper->func);
|
||||
helper->func (ret, helper->user_data);
|
||||
|
||||
g_free (helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_async:
|
||||
* @details: NULL-terminated array of installer string details (see below)
|
||||
* @ctx: a #GstInstallPluginsContext, or NULL
|
||||
* @func: the function to call when the installer program returns
|
||||
* @user_data: the user data to pass to @func when called, or NULL
|
||||
*
|
||||
* Requests plugin installation without blocking. Once the plugins have been
|
||||
* installed or installation has failed, @func will be called with the result
|
||||
* of the installation and your provided @user_data pointer.
|
||||
*
|
||||
* This function requires a running GLib/Gtk main loop. If you are not
|
||||
* running a GLib/Gtk main loop, make sure to regularly call
|
||||
* g_main_context_iteration(NULL,FALSE).
|
||||
*
|
||||
* The installer strings that make up @detail are typically obtained by
|
||||
* calling gst_missing_plugin_message_get_installer_detail() on missing-plugin
|
||||
* messages that have been caught on a pipeline's bus or created by the
|
||||
* application via the provided API, such as gst_missing_element_message_new().
|
||||
*
|
||||
* Returns: result code whether an external installer could be started
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
|
||||
GstInstallPluginsReturn
|
||||
gst_install_plugins_async (gchar ** details, GstInstallPluginsContext * ctx,
|
||||
GstInstallPluginsResultFunc func, gpointer user_data)
|
||||
{
|
||||
GstInstallPluginsAsyncHelper *helper;
|
||||
GPid pid;
|
||||
|
||||
g_return_val_if_fail (details != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
g_return_val_if_fail (func != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
|
||||
if (install_in_progress)
|
||||
return GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS;
|
||||
|
||||
/* if we can't access our helper, don't bother */
|
||||
if (!g_file_test (gst_install_plugins_get_helper (),
|
||||
G_FILE_TEST_IS_EXECUTABLE))
|
||||
return GST_INSTALL_PLUGINS_HELPER_MISSING;
|
||||
|
||||
if (!gst_install_plugins_spawn_child (details, ctx, &pid, NULL))
|
||||
return GST_INSTALL_PLUGINS_INTERNAL_FAILURE;
|
||||
|
||||
helper = g_new (GstInstallPluginsAsyncHelper, 1);
|
||||
helper->func = func;
|
||||
helper->user_data = user_data;
|
||||
|
||||
g_child_watch_add (pid, gst_install_plugins_installer_exited, helper);
|
||||
|
||||
return GST_INSTALL_PLUGINS_STARTED_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_sync:
|
||||
* @details: NULL-terminated array of installer string details
|
||||
* @ctx: a #GstInstallPluginsContext, or NULL
|
||||
*
|
||||
* Requests plugin installation and block until the plugins have been
|
||||
* installed or installation has failed.
|
||||
*
|
||||
* This function should almost never be used, it only exists for cases where
|
||||
* a non-GLib main loop is running and the user wants to run it in a separate
|
||||
* thread and marshal the result back asynchronously into the main thread
|
||||
* using the other non-GLib main loop. You should almost always use
|
||||
* gst_install_plugins_async() instead of this function.
|
||||
*
|
||||
* Returns: the result of the installation.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
GstInstallPluginsReturn
|
||||
gst_install_plugins_sync (gchar ** details, GstInstallPluginsContext * ctx)
|
||||
{
|
||||
gint status;
|
||||
|
||||
g_return_val_if_fail (details != NULL, GST_INSTALL_PLUGINS_INTERNAL_FAILURE);
|
||||
|
||||
if (install_in_progress)
|
||||
return GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS;
|
||||
|
||||
/* if we can't access our helper, don't bother */
|
||||
if (!g_file_test (gst_install_plugins_get_helper (),
|
||||
G_FILE_TEST_IS_EXECUTABLE))
|
||||
return GST_INSTALL_PLUGINS_HELPER_MISSING;
|
||||
|
||||
if (!gst_install_plugins_spawn_child (details, ctx, NULL, &status))
|
||||
return GST_INSTALL_PLUGINS_INTERNAL_FAILURE;
|
||||
|
||||
return gst_install_plugins_return_from_status (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_return_get_name:
|
||||
* @ret: the return status code
|
||||
*
|
||||
* Convenience function to return the descriptive string associated
|
||||
* with a status code. This function returns English strings and
|
||||
* should not be used for user messages. It is here only to assist
|
||||
* in debugging.
|
||||
*
|
||||
* Returns: a descriptive string for the status code in @ret
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
const gchar *
|
||||
gst_install_plugins_return_get_name (GstInstallPluginsReturn ret)
|
||||
{
|
||||
switch (ret) {
|
||||
case GST_INSTALL_PLUGINS_SUCCESS:
|
||||
return "success";
|
||||
case GST_INSTALL_PLUGINS_NOT_FOUND:
|
||||
return "not-found";
|
||||
case GST_INSTALL_PLUGINS_ERROR:
|
||||
return "install-error";
|
||||
case GST_INSTALL_PLUGINS_CRASHED:
|
||||
return "installer-exit-unclean";
|
||||
case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
|
||||
return "partial-success";
|
||||
case GST_INSTALL_PLUGINS_USER_ABORT:
|
||||
return "user-abort";
|
||||
case GST_INSTALL_PLUGINS_STARTED_OK:
|
||||
return "started-ok";
|
||||
case GST_INSTALL_PLUGINS_INTERNAL_FAILURE:
|
||||
return "internal-failure";
|
||||
case GST_INSTALL_PLUGINS_HELPER_MISSING:
|
||||
return "helper-missing";
|
||||
case GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS:
|
||||
return "install-in-progress";
|
||||
case GST_INSTALL_PLUGINS_INVALID:
|
||||
return "invalid";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "(UNKNOWN)";
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_install_plugins_installation_in_progress:
|
||||
*
|
||||
* Checks whether plugin installation (initiated by this application only)
|
||||
* is currently in progress.
|
||||
*
|
||||
* Returns: TRUE if plugin installation is in progress, otherwise FALSE
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
gboolean
|
||||
gst_install_plugins_installation_in_progress (void)
|
||||
{
|
||||
return install_in_progress;
|
||||
}
|
137
gst-libs/gst/utils/install-plugins.h
Normal file
137
gst-libs/gst/utils/install-plugins.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* GStreamer base utils library plugin install support for applications
|
||||
* Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
|
||||
* Copyright (C) 2006 Ryan Lortie <desrt desrt ca>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GST_BASE_UTILS_INSTALL_PLUGINS_H__
|
||||
#define __GST_BASE_UTILS_INSTALL_PLUGINS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* functions for use by applications to initiate installation of missing plugins
|
||||
*/
|
||||
|
||||
/**
|
||||
* GstInstallPluginsReturn:
|
||||
* @GST_INSTALL_PLUGINS_SUCCESS: all of the requested plugins could be
|
||||
* installed
|
||||
* @GST_INSTALL_PLUGINS_NOT_FOUND: no appropriate installation candidate for
|
||||
* any of the requested plugins could be found. Only return this if nothing
|
||||
* has been installed. Return #GST_INSTALL_PLUGINS_PARTIAL_SUCCESS if
|
||||
* some (but not all) of the requested plugins could be installed.
|
||||
* @GST_INSTALL_PLUGINS_ERROR: an error occured during the installation. If
|
||||
* this happens, the user has already seen an error message and another
|
||||
* one should not be displayed
|
||||
* @GST_INSTALL_PLUGINS_CRASHED: the installer had an unclean exit code
|
||||
* (ie. death by signal)
|
||||
* @GST_INSTALL_PLUGINS_PARTIAL_SUCCESS: some of the requested plugins could
|
||||
* be installed, but not all
|
||||
* @GST_INSTALL_PLUGINS_USER_ABORT: the user has aborted the installation
|
||||
* @GST_INSTALL_PLUGINS_INVALID: the helper returned an invalid status code
|
||||
* @GST_INSTALL_PLUGINS_STARTED_OK: returned by gst_install_plugins_async() to
|
||||
* indicate that everything went fine so far and the provided callback
|
||||
* will be called with the result of the installation later
|
||||
* @GST_INSTALL_PLUGINS_INTERNAL_FAILURE: some internal failure has
|
||||
* occured when trying to start the installer
|
||||
* @GST_INSTALL_PLUGINS_HELPER_MISSING: the helper script to call the
|
||||
* actual installer is not installed
|
||||
* @GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS: a previously-started plugin
|
||||
* installation is still in progress, try again later
|
||||
*
|
||||
* Result codes returned by gst_install_plugins_async() and
|
||||
* gst_install_plugins_sync(), and also the result code passed to the
|
||||
* #GstInstallPluginsResultFunc specified with gst_install_plugin_async().
|
||||
*
|
||||
* These codes indicate success or failure of starting an external installer
|
||||
* program and to what extent the requested plugins could be installed.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef enum {
|
||||
/* Return codes from the installer. Returned by gst_install_plugins_sync(),
|
||||
* or passed as result code to your #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_SUCCESS = 0,
|
||||
GST_INSTALL_PLUGINS_NOT_FOUND = 1,
|
||||
GST_INSTALL_PLUGINS_ERROR = 2,
|
||||
GST_INSTALL_PLUGINS_PARTIAL_SUCCESS = 3,
|
||||
GST_INSTALL_PLUGINS_USER_ABORT = 4,
|
||||
|
||||
/* Returned by gst_install_plugins_sync(), or passed as result code to your
|
||||
* #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_CRASHED = 100,
|
||||
GST_INSTALL_PLUGINS_INVALID,
|
||||
|
||||
/* Return codes from starting the external helper, may be returned by both
|
||||
* gst_install_plugins_sync() and gst_install_plugins_async(), but should
|
||||
* never be seen by a #GstInstallPluginsResultFunc */
|
||||
GST_INSTALL_PLUGINS_STARTED_OK = 200,
|
||||
GST_INSTALL_PLUGINS_INTERNAL_FAILURE,
|
||||
GST_INSTALL_PLUGINS_HELPER_MISSING,
|
||||
GST_INSTALL_PLUGINS_INSTALL_IN_PROGRESS
|
||||
} GstInstallPluginsReturn;
|
||||
|
||||
/**
|
||||
* GstInstallPluginsContext:
|
||||
*
|
||||
* Opaque context structure for the plugin installation. Use the provided
|
||||
* API to set details on it.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef struct _GstInstallPluginsContext GstInstallPluginsContext;
|
||||
|
||||
GstInstallPluginsContext * gst_install_plugins_context_new (void);
|
||||
|
||||
void gst_install_plugins_context_free (GstInstallPluginsContext * ctx);
|
||||
|
||||
void gst_install_plugins_context_set_xid (GstInstallPluginsContext * ctx,
|
||||
guint xid);
|
||||
|
||||
/**
|
||||
* GstInstallPluginsResultFunc:
|
||||
* @result: whether the installation of the requested plugins succeeded or not
|
||||
* @user_data: the user data passed to gst_install_plugins_async()
|
||||
*
|
||||
* The prototype of the callback function that will be called once the
|
||||
* external plugin installer program has returned. You only need to provide
|
||||
* a callback function if you are using the asynchronous interface.
|
||||
*
|
||||
* Since: 0.10.12
|
||||
*/
|
||||
typedef void (*GstInstallPluginsResultFunc) (GstInstallPluginsReturn result,
|
||||
gpointer user_data);
|
||||
|
||||
GstInstallPluginsReturn gst_install_plugins_async (gchar ** details,
|
||||
GstInstallPluginsContext * ctx,
|
||||
GstInstallPluginsResultFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
GstInstallPluginsReturn gst_install_plugins_sync (gchar ** details,
|
||||
GstInstallPluginsContext * ctx);
|
||||
|
||||
const gchar * gst_install_plugins_return_get_name (GstInstallPluginsReturn ret);
|
||||
|
||||
gboolean gst_install_plugins_installation_in_progress (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_BASE_UTILS_INSTALL_PLUGINS_H__ */
|
||||
|
|
@ -24,7 +24,22 @@
|
|||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/utils/base-utils.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for unlink() */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h> /* for fchmod() */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h> /* for fchmod() */
|
||||
#endif
|
||||
|
||||
static void
|
||||
missing_msg_check_getters (GstMessage * msg)
|
||||
|
@ -400,6 +415,8 @@ GST_START_TEST (test_base_utils_get_codec_description)
|
|||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_base_utils_taglist_add_codec_info)
|
||||
{
|
||||
GstTagList *list;
|
||||
|
@ -430,6 +447,141 @@ GST_START_TEST (test_base_utils_taglist_add_codec_info)
|
|||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static gint marker;
|
||||
|
||||
static void
|
||||
result_cb (GstInstallPluginsReturn result, gpointer user_data)
|
||||
{
|
||||
GST_LOG ("result = %u, user_data = %p", result, user_data);
|
||||
|
||||
fail_unless (user_data == (gpointer) & marker);
|
||||
|
||||
marker = result;
|
||||
}
|
||||
|
||||
#define FAKE_INSTALL_PLUGINS_HELPER "/tmp/gst-plugins-base-unit-test-helper"
|
||||
#define SCRIPT_NO_XID \
|
||||
"#!/bin/sh\n" \
|
||||
"if test x$1 != xdetail1; then exit 21; fi;\n" \
|
||||
"if test x$2 != xdetail2; then exit 22; fi;\n" \
|
||||
"exit 1\n"
|
||||
|
||||
#define SCRIPT_WITH_XID \
|
||||
"#!/bin/sh\n" \
|
||||
"if test x$1 != 'x--transient-for=42'; then exit 21; fi;\n" \
|
||||
"if test x$2 != xdetail1; then exit 22; fi;\n" \
|
||||
"if test x$3 != xdetail2; then exit 23; fi;\n" \
|
||||
"exit 0\n"
|
||||
|
||||
/* make sure our script gets called with the right parameters */
|
||||
static void
|
||||
test_base_utils_install_plugins_do_callout (gchar ** details,
|
||||
GstInstallPluginsContext * ctx, const gchar * script,
|
||||
GstInstallPluginsReturn expected_result)
|
||||
{
|
||||
#ifdef G_OS_UNIX
|
||||
GstInstallPluginsReturn ret;
|
||||
FILE *f;
|
||||
|
||||
unlink (FAKE_INSTALL_PLUGINS_HELPER);
|
||||
|
||||
f = g_fopen (FAKE_INSTALL_PLUGINS_HELPER, "w");
|
||||
if (f == NULL)
|
||||
return;
|
||||
if (g_fprintf (f, "%s", script) > 0 &&
|
||||
fchmod (fileno (f), S_IRUSR | S_IWUSR | S_IXUSR) == 0) {
|
||||
fclose (f);
|
||||
g_setenv ("GST_INSTALL_PLUGINS_HELPER", FAKE_INSTALL_PLUGINS_HELPER, 1);
|
||||
|
||||
/* test sync callout */
|
||||
ret = gst_install_plugins_sync (details, ctx);
|
||||
fail_unless (ret == GST_INSTALL_PLUGINS_HELPER_MISSING ||
|
||||
ret == expected_result,
|
||||
"gst_install_plugins_sync() failed with unexpected ret %d, which is"
|
||||
"neither HELPER_MISSING NOR %d", ret, expected_result);
|
||||
|
||||
/* test async callout */
|
||||
marker = -333;
|
||||
ret = gst_install_plugins_async (details, ctx, result_cb,
|
||||
(gpointer) & marker);
|
||||
fail_unless (ret == GST_INSTALL_PLUGINS_HELPER_MISSING ||
|
||||
ret == GST_INSTALL_PLUGINS_STARTED_OK,
|
||||
"gst_install_plugins_async() failed with unexpected ret %d", ret);
|
||||
if (ret == GST_INSTALL_PLUGINS_STARTED_OK) {
|
||||
while (marker == -333) {
|
||||
g_usleep (500);
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
}
|
||||
/* and check that the callback was called with the expected code */
|
||||
fail_unless_equals_int (marker, expected_result);
|
||||
}
|
||||
} else {
|
||||
fclose (f);
|
||||
}
|
||||
unlink (FAKE_INSTALL_PLUGINS_HELPER);
|
||||
#endif /* G_OS_UNIX */
|
||||
}
|
||||
|
||||
GST_START_TEST (test_base_utils_install_plugins)
|
||||
{
|
||||
GstInstallPluginsContext *ctx;
|
||||
GstInstallPluginsReturn ret;
|
||||
gchar *details[] = { "detail1", "detail2" };
|
||||
|
||||
ctx = gst_install_plugins_context_new ();
|
||||
|
||||
ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx);
|
||||
);
|
||||
ASSERT_CRITICAL (ret =
|
||||
gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker);
|
||||
);
|
||||
ASSERT_CRITICAL (ret =
|
||||
gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker);
|
||||
);
|
||||
|
||||
/* make sure the functions return the right error code if the helper does
|
||||
* not exist */
|
||||
g_setenv ("GST_INSTALL_PLUGINS_HELPER", "/does/not/ex/is.t", 1);
|
||||
ret = gst_install_plugins_sync (details, NULL);
|
||||
fail_unless_equals_int (ret, GST_INSTALL_PLUGINS_HELPER_MISSING);
|
||||
|
||||
marker = -333;
|
||||
ret =
|
||||
gst_install_plugins_async (details, NULL, result_cb, (gpointer) & marker);
|
||||
fail_unless_equals_int (ret, GST_INSTALL_PLUGINS_HELPER_MISSING);
|
||||
/* and check that the callback wasn't called */
|
||||
fail_unless_equals_int (marker, -333);
|
||||
|
||||
/* now make sure our scripts are actually called as expected (if possible) */
|
||||
test_base_utils_install_plugins_do_callout (details, NULL, SCRIPT_NO_XID,
|
||||
GST_INSTALL_PLUGINS_NOT_FOUND);
|
||||
|
||||
/* and again with context */
|
||||
gst_install_plugins_context_set_xid (ctx, 42);
|
||||
test_base_utils_install_plugins_do_callout (details, ctx, SCRIPT_WITH_XID,
|
||||
GST_INSTALL_PLUGINS_SUCCESS);
|
||||
|
||||
/* and free the context now that we don't need it any longer */
|
||||
gst_install_plugins_context_free (ctx);
|
||||
|
||||
/* completely silly test to check gst_install_plugins_return_get_name()
|
||||
* is somewhat well-behaved */
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = -99; i < 16738; ++i) {
|
||||
const gchar *s;
|
||||
|
||||
s = gst_install_plugins_return_get_name ((GstInstallPluginsReturn) i);
|
||||
fail_unless (s != NULL);
|
||||
/* GST_LOG ("%5d = %s", i, s); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
libgstbaseutils_suite (void)
|
||||
{
|
||||
|
@ -441,6 +593,7 @@ libgstbaseutils_suite (void)
|
|||
tcase_add_test (tc_chain, test_base_utils_post_missing_messages);
|
||||
tcase_add_test (tc_chain, test_base_utils_taglist_add_codec_info);
|
||||
tcase_add_test (tc_chain, test_base_utils_get_codec_description);
|
||||
tcase_add_test (tc_chain, test_base_utils_install_plugins);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,22 @@
|
|||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/utils/base-utils.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for unlink() */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h> /* for fchmod() */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h> /* for fchmod() */
|
||||
#endif
|
||||
|
||||
static void
|
||||
missing_msg_check_getters (GstMessage * msg)
|
||||
|
@ -400,6 +415,8 @@ GST_START_TEST (test_base_utils_get_codec_description)
|
|||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_base_utils_taglist_add_codec_info)
|
||||
{
|
||||
GstTagList *list;
|
||||
|
@ -430,6 +447,141 @@ GST_START_TEST (test_base_utils_taglist_add_codec_info)
|
|||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static gint marker;
|
||||
|
||||
static void
|
||||
result_cb (GstInstallPluginsReturn result, gpointer user_data)
|
||||
{
|
||||
GST_LOG ("result = %u, user_data = %p", result, user_data);
|
||||
|
||||
fail_unless (user_data == (gpointer) & marker);
|
||||
|
||||
marker = result;
|
||||
}
|
||||
|
||||
#define FAKE_INSTALL_PLUGINS_HELPER "/tmp/gst-plugins-base-unit-test-helper"
|
||||
#define SCRIPT_NO_XID \
|
||||
"#!/bin/sh\n" \
|
||||
"if test x$1 != xdetail1; then exit 21; fi;\n" \
|
||||
"if test x$2 != xdetail2; then exit 22; fi;\n" \
|
||||
"exit 1\n"
|
||||
|
||||
#define SCRIPT_WITH_XID \
|
||||
"#!/bin/sh\n" \
|
||||
"if test x$1 != 'x--transient-for=42'; then exit 21; fi;\n" \
|
||||
"if test x$2 != xdetail1; then exit 22; fi;\n" \
|
||||
"if test x$3 != xdetail2; then exit 23; fi;\n" \
|
||||
"exit 0\n"
|
||||
|
||||
/* make sure our script gets called with the right parameters */
|
||||
static void
|
||||
test_base_utils_install_plugins_do_callout (gchar ** details,
|
||||
GstInstallPluginsContext * ctx, const gchar * script,
|
||||
GstInstallPluginsReturn expected_result)
|
||||
{
|
||||
#ifdef G_OS_UNIX
|
||||
GstInstallPluginsReturn ret;
|
||||
FILE *f;
|
||||
|
||||
unlink (FAKE_INSTALL_PLUGINS_HELPER);
|
||||
|
||||
f = g_fopen (FAKE_INSTALL_PLUGINS_HELPER, "w");
|
||||
if (f == NULL)
|
||||
return;
|
||||
if (g_fprintf (f, "%s", script) > 0 &&
|
||||
fchmod (fileno (f), S_IRUSR | S_IWUSR | S_IXUSR) == 0) {
|
||||
fclose (f);
|
||||
g_setenv ("GST_INSTALL_PLUGINS_HELPER", FAKE_INSTALL_PLUGINS_HELPER, 1);
|
||||
|
||||
/* test sync callout */
|
||||
ret = gst_install_plugins_sync (details, ctx);
|
||||
fail_unless (ret == GST_INSTALL_PLUGINS_HELPER_MISSING ||
|
||||
ret == expected_result,
|
||||
"gst_install_plugins_sync() failed with unexpected ret %d, which is"
|
||||
"neither HELPER_MISSING NOR %d", ret, expected_result);
|
||||
|
||||
/* test async callout */
|
||||
marker = -333;
|
||||
ret = gst_install_plugins_async (details, ctx, result_cb,
|
||||
(gpointer) & marker);
|
||||
fail_unless (ret == GST_INSTALL_PLUGINS_HELPER_MISSING ||
|
||||
ret == GST_INSTALL_PLUGINS_STARTED_OK,
|
||||
"gst_install_plugins_async() failed with unexpected ret %d", ret);
|
||||
if (ret == GST_INSTALL_PLUGINS_STARTED_OK) {
|
||||
while (marker == -333) {
|
||||
g_usleep (500);
|
||||
g_main_context_iteration (NULL, FALSE);
|
||||
}
|
||||
/* and check that the callback was called with the expected code */
|
||||
fail_unless_equals_int (marker, expected_result);
|
||||
}
|
||||
} else {
|
||||
fclose (f);
|
||||
}
|
||||
unlink (FAKE_INSTALL_PLUGINS_HELPER);
|
||||
#endif /* G_OS_UNIX */
|
||||
}
|
||||
|
||||
GST_START_TEST (test_base_utils_install_plugins)
|
||||
{
|
||||
GstInstallPluginsContext *ctx;
|
||||
GstInstallPluginsReturn ret;
|
||||
gchar *details[] = { "detail1", "detail2" };
|
||||
|
||||
ctx = gst_install_plugins_context_new ();
|
||||
|
||||
ASSERT_CRITICAL (ret = gst_install_plugins_sync (NULL, ctx);
|
||||
);
|
||||
ASSERT_CRITICAL (ret =
|
||||
gst_install_plugins_async (NULL, ctx, result_cb, (gpointer) & marker);
|
||||
);
|
||||
ASSERT_CRITICAL (ret =
|
||||
gst_install_plugins_async (details, ctx, NULL, (gpointer) & marker);
|
||||
);
|
||||
|
||||
/* make sure the functions return the right error code if the helper does
|
||||
* not exist */
|
||||
g_setenv ("GST_INSTALL_PLUGINS_HELPER", "/does/not/ex/is.t", 1);
|
||||
ret = gst_install_plugins_sync (details, NULL);
|
||||
fail_unless_equals_int (ret, GST_INSTALL_PLUGINS_HELPER_MISSING);
|
||||
|
||||
marker = -333;
|
||||
ret =
|
||||
gst_install_plugins_async (details, NULL, result_cb, (gpointer) & marker);
|
||||
fail_unless_equals_int (ret, GST_INSTALL_PLUGINS_HELPER_MISSING);
|
||||
/* and check that the callback wasn't called */
|
||||
fail_unless_equals_int (marker, -333);
|
||||
|
||||
/* now make sure our scripts are actually called as expected (if possible) */
|
||||
test_base_utils_install_plugins_do_callout (details, NULL, SCRIPT_NO_XID,
|
||||
GST_INSTALL_PLUGINS_NOT_FOUND);
|
||||
|
||||
/* and again with context */
|
||||
gst_install_plugins_context_set_xid (ctx, 42);
|
||||
test_base_utils_install_plugins_do_callout (details, ctx, SCRIPT_WITH_XID,
|
||||
GST_INSTALL_PLUGINS_SUCCESS);
|
||||
|
||||
/* and free the context now that we don't need it any longer */
|
||||
gst_install_plugins_context_free (ctx);
|
||||
|
||||
/* completely silly test to check gst_install_plugins_return_get_name()
|
||||
* is somewhat well-behaved */
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = -99; i < 16738; ++i) {
|
||||
const gchar *s;
|
||||
|
||||
s = gst_install_plugins_return_get_name ((GstInstallPluginsReturn) i);
|
||||
fail_unless (s != NULL);
|
||||
/* GST_LOG ("%5d = %s", i, s); */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
libgstbaseutils_suite (void)
|
||||
{
|
||||
|
@ -441,6 +593,7 @@ libgstbaseutils_suite (void)
|
|||
tcase_add_test (tc_chain, test_base_utils_post_missing_messages);
|
||||
tcase_add_test (tc_chain, test_base_utils_taglist_add_codec_info);
|
||||
tcase_add_test (tc_chain, test_base_utils_get_codec_description);
|
||||
tcase_add_test (tc_chain, test_base_utils_install_plugins);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue