1
/* totem-missing-plugins.c
3
Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
5
The Gnome Library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public License as
7
published by the Free Software Foundation; either version 2 of the
8
License, or (at your option) any later version.
10
The Gnome Library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with the Gnome Library; see the file COPYING.LIB. If not,
17
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA.
20
Author: Tim-Philipp Müller <tim centricular net>
25
#include "totem-missing-plugins.h"
27
#ifdef ENABLE_MISSING_PLUGIN_INSTALLATION
29
#include "totem-private.h"
30
#include "bacon-video-widget.h"
32
#include <gst/pbutils/pbutils.h>
33
#include <gst/pbutils/install-plugins.h>
35
#include <gst/gst.h> /* for gst_registry_update */
39
#ifdef GDK_WINDOWING_X11
45
GST_DEBUG_CATEGORY_EXTERN (_totem_gst_debug_cat);
46
#define GST_CAT_DEFAULT _totem_gst_debug_cat
48
/* list of blacklisted detail strings */
49
static GList *blacklisted_plugins = NULL;
58
TotemCodecInstallContext;
61
totem_codec_install_plugin_is_blacklisted (const gchar * detail)
65
res = g_list_find_custom (blacklisted_plugins,
67
(GCompareFunc) strcmp);
73
totem_codec_install_blacklist_plugin (const gchar * detail)
75
if (!totem_codec_install_plugin_is_blacklisted (detail))
77
blacklisted_plugins = g_list_prepend (blacklisted_plugins,
83
totem_codec_install_context_free (TotemCodecInstallContext *ctx)
85
g_strfreev (ctx->descriptions);
86
g_strfreev (ctx->details);
91
on_plugin_installation_done (GstInstallPluginsReturn res, gpointer user_data)
93
TotemCodecInstallContext *ctx = (TotemCodecInstallContext *) user_data;
96
GST_INFO ("res = %d (%s)", res, gst_install_plugins_return_get_name (res));
100
/* treat partial success the same as success; in the worst case we'll
101
* just do another round and get NOT_FOUND as result that time */
102
case GST_INSTALL_PLUGINS_PARTIAL_SUCCESS:
103
case GST_INSTALL_PLUGINS_SUCCESS:
105
/* blacklist installed plugins too, so that we don't get
106
* into endless installer loops in case of inconsistencies */
107
for (p = ctx->details; p != NULL && *p != NULL; ++p)
108
totem_codec_install_blacklist_plugin (*p);
110
bacon_video_widget_stop (ctx->totem->bvw);
111
g_message ("Missing plugins installed. Updating plugin registry ...");
113
/* force GStreamer to re-read its plugin registry */
114
if (gst_update_registry ())
116
g_message ("Plugin registry updated, trying again.");
117
bacon_video_widget_play (ctx->totem->bvw, NULL);
119
g_warning ("GStreamer registry update failed");
120
/* FIXME: should we show an error message here? */
124
case GST_INSTALL_PLUGINS_NOT_FOUND:
126
g_message ("No installation candidate for missing plugins found.");
128
/* NOT_FOUND should only be returned if not a single one of the
129
* requested plugins was found; if we managed to play something
130
* anyway, we should just continue playing what we have and
131
* blacklist the requested plugins for this session; if we
132
* could not play anything we should blacklist them as well,
133
* so the install wizard isn't called again for nothing */
134
for (p = ctx->details; p != NULL && *p != NULL; ++p)
135
totem_codec_install_blacklist_plugin (*p);
139
bacon_video_widget_play (ctx->totem->bvw, NULL);
141
/* wizard has not shown error, do stop/play again,
142
* so that an error message gets shown */
143
bacon_video_widget_stop (ctx->totem->bvw);
144
bacon_video_widget_play (ctx->totem->bvw, NULL);
148
case GST_INSTALL_PLUGINS_USER_ABORT:
150
/* blacklist on user abort, so we show an error next time (or
151
* just play what we can) instead of calling the installer */
152
for (p = ctx->details; p != NULL && *p != NULL; ++p)
153
totem_codec_install_blacklist_plugin (*p);
156
bacon_video_widget_play (ctx->totem->bvw, NULL);
158
/* if we couldn't play anything, do stop/play again,
159
* so that an error message gets shown */
160
bacon_video_widget_stop (ctx->totem->bvw);
161
bacon_video_widget_play (ctx->totem->bvw, NULL);
165
case GST_INSTALL_PLUGINS_ERROR:
166
case GST_INSTALL_PLUGINS_CRASHED:
169
g_message ("Missing plugin installation failed: %s",
170
gst_install_plugins_return_get_name (res));
173
bacon_video_widget_play (ctx->totem->bvw, NULL);
175
bacon_video_widget_stop (ctx->totem->bvw);
180
totem_codec_install_context_free (ctx);
184
totem_on_missing_plugins_event (BaconVideoWidget *bvw, char **details,
185
char **descriptions, gboolean playing,
188
GstInstallPluginsContext *install_ctx;
189
TotemCodecInstallContext *ctx;
190
GstInstallPluginsReturn status;
193
num = g_strv_length (details);
194
g_return_val_if_fail (num > 0 && g_strv_length (descriptions) == num, FALSE);
196
ctx = g_new0 (TotemCodecInstallContext, 1);
197
ctx->descriptions = g_strdupv (descriptions);
198
ctx->details = g_strdupv (details);
199
ctx->playing = playing;
202
for (i = 0; i < num; ++i)
204
if (totem_codec_install_plugin_is_blacklisted (ctx->details[i]))
206
g_message ("Missing plugin: %s (ignoring)", ctx->details[i]);
207
g_free (ctx->details[i]);
208
g_free (ctx->descriptions[i]);
209
ctx->details[i] = ctx->details[num-1];
210
ctx->descriptions[i] = ctx->descriptions[num-1];
211
ctx->details[num-1] = NULL;
212
ctx->descriptions[num-1] = NULL;
216
g_message ("Missing plugin: %s (%s)", ctx->details[i], ctx->descriptions[i]);
222
g_message ("All missing plugins are blacklisted, doing nothing");
223
totem_codec_install_context_free (ctx);
227
install_ctx = gst_install_plugins_context_new ();
229
#ifdef GDK_WINDOWING_X11
230
if (totem->win != NULL && GTK_WIDGET_REALIZED (totem->win))
234
xid = GDK_WINDOW_XWINDOW (GTK_WIDGET (totem->win)->window);
235
gst_install_plugins_context_set_xid (install_ctx, xid);
239
status = gst_install_plugins_async (ctx->details, install_ctx,
240
on_plugin_installation_done,
243
gst_install_plugins_context_free (install_ctx);
245
GST_INFO ("gst_install_plugins_async() result = %d", status);
247
if (status != GST_INSTALL_PLUGINS_STARTED_OK)
249
if (status == GST_INSTALL_PLUGINS_HELPER_MISSING)
251
g_message ("Automatic missing codec installation not supported "
252
"(helper script missing)");
254
g_warning ("Failed to start codec installation: %s",
255
gst_install_plugins_return_get_name (status));
257
totem_codec_install_context_free (ctx);
261
/* if we managed to start playing, pause playback, since some install
262
* wizard should now take over in a second anyway and the user might not
263
* be able to use totem's controls while the wizard is running */
265
bacon_video_widget_pause (bvw);
270
#endif /* ENABLE_MISSING_PLUGIN_INSTALLATION */
273
totem_missing_plugins_setup (Totem *totem)
275
#ifdef ENABLE_MISSING_PLUGIN_INSTALLATION
276
g_signal_connect (G_OBJECT (totem->bvw),
278
G_CALLBACK (totem_on_missing_plugins_event),
281
gst_pb_utils_init ();
283
GST_INFO ("Set up support for automatic missing plugin installation");