gst/real/: Use GModule instead of using dlsym() directly. Fixes #430598.

Original commit message from CVS:
* gst/real/gstrealaudiodec.c: (gst_real_audio_dec_setcaps),
(gst_real_audio_dec_finalize):
* gst/real/gstrealaudiodec.h:
* gst/real/gstrealvideodec.c: (open_library), (close_library):
* gst/real/gstrealvideodec.h:
Use GModule instead of using dlsym() directly. Fixes #430598.
This commit is contained in:
Tim-Philipp Müller 2007-05-06 15:25:05 +00:00
parent fcfbf0f58c
commit e792718ddf
5 changed files with 95 additions and 61 deletions

View file

@ -1,3 +1,12 @@
2007-05-06 Tim-Philipp Müller <tim at centricular dot net>
* gst/real/gstrealaudiodec.c: (gst_real_audio_dec_setcaps),
(gst_real_audio_dec_finalize):
* gst/real/gstrealaudiodec.h:
* gst/real/gstrealvideodec.c: (open_library), (close_library):
* gst/real/gstrealvideodec.h:
Use GModule instead of using dlsym() directly. Fixes #430598.
2007-05-04 Sebastien Moutte <sebastien@moutte.net>
* docs/plugins/gst-plugins-bad-plugins-docs.sgml:

View file

@ -1,7 +1,7 @@
/* GStreamer
*
* Copyright (C) 2006 Lutz Mueller <lutz@topfrose.de>
* 2006 Edward Hervey <bilboed@bilboed.com>
* Copyright (C) 2006 Edward Hervey <bilboed@bilboed.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -25,7 +25,6 @@
#include "gstrealaudiodec.h"
#include <dlfcn.h>
#include <string.h>
GST_DEBUG_CATEGORY_STATIC (real_audio_dec_debug);
@ -115,7 +114,7 @@ struct _GstRealAudioDec
guint width, height, leaf_size;
/* Hooks */
gpointer handle;
GModule *module;
RealFunctions funcs;
/* Used by the REAL library. */
@ -169,6 +168,9 @@ gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps)
{
GstRealAudioDec *dec = GST_REAL_AUDIO_DEC (GST_PAD_PARENT (pad));
GstStructure *s = gst_caps_get_structure (caps, 0);
gpointer ra_close_codec, ra_decode, ra_free_decoder;
gpointer ra_open_codec2, ra_init_decoder, ra_set_flavor;
gpointer set_dll_access_path = NULL, ra_set_pwd = NULL;
gchar *path;
gint version, flavor, channels, rate, leaf_size, packet_size, width, height;
guint16 res;
@ -177,8 +179,9 @@ gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps)
const GValue *v;
GstBuffer *buf = NULL;
const gchar *name = gst_structure_get_name (s);
gpointer context = NULL, handle;
RealFunctions funcs;
GModule *module;
gpointer context = NULL;
RealFunctions funcs = { NULL, };
if (!strcmp (name, "audio/x-sipro"))
version = GST_REAL_AUDIO_DEC_VERSION_SIPR;
@ -218,25 +221,34 @@ gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps)
goto unknown_version;
}
handle = dlopen (path, RTLD_LAZY);
if (!handle)
goto could_not_open;
funcs.RACloseCodec = dlsym (handle, "RACloseCodec");
funcs.RADecode = dlsym (handle, "RADecode");
funcs.RAFreeDecoder = dlsym (handle, "RAFreeDecoder");
funcs.RAOpenCodec2 = dlsym (handle, "RAOpenCodec2");
funcs.RAInitDecoder = dlsym (handle, "RAInitDecoder");
funcs.RASetFlavor = dlsym (handle, "RASetFlavor");
funcs.SetDLLAccessPath = dlsym (handle, "SetDLLAccessPath");
funcs.RASetPwd = dlsym (handle, "RASetPwd");
if (!(funcs.RACloseCodec && funcs.RADecode &&
funcs.RAFreeDecoder && funcs.RAOpenCodec2 &&
funcs.RAInitDecoder && funcs.RASetFlavor))
goto could_not_load;
module = g_module_open (path, G_MODULE_BIND_LAZY);
if (funcs.SetDLLAccessPath)
if (module == NULL)
goto could_not_open;
if (!g_module_symbol (module, "RACloseCodec", &ra_close_codec) ||
!g_module_symbol (module, "RADecode", &ra_decode) ||
!g_module_symbol (module, "RAFreeDecoder", &ra_free_decoder) ||
!g_module_symbol (module, "RAOpenCodec2", &ra_open_codec2) ||
!g_module_symbol (module, "RAInitDecoder", &ra_init_decoder) ||
!g_module_symbol (module, "RASetFlavor", &ra_set_flavor)) {
goto could_not_load;
}
g_module_symbol (module, "RASetPwd", &ra_set_pwd);
if (g_module_symbol (module, "SetDLLAccessPath", &set_dll_access_path))
funcs.SetDLLAccessPath (DEFAULT_PATH);
funcs.RACloseCodec = ra_close_codec;
funcs.RADecode = ra_decode;
funcs.RAFreeDecoder = ra_free_decoder;
funcs.RAOpenCodec2 = ra_open_codec2;
funcs.RAInitDecoder = ra_init_decoder;
funcs.RASetFlavor = ra_set_flavor;
funcs.RASetPwd = ra_set_pwd;
funcs.SetDLLAccessPath = set_dll_access_path;
if ((res = funcs.RAOpenCodec2 (&context, NULL))) {
GST_DEBUG_OBJECT (dec, "RAOpenCodec2() failed");
goto could_not_initialize;
@ -284,9 +296,9 @@ gst_real_audio_dec_setcaps (GstPad * pad, GstCaps * caps)
dec->funcs.RAFreeDecoder (dec->context);
}
dec->context = context;
if (dec->handle)
dlclose (dec->handle);
dec->handle = handle;
if (dec->module)
g_module_close (dec->module);
dec->module = module;
dec->funcs = funcs;
return TRUE;
@ -298,18 +310,19 @@ unknown_version:
GST_DEBUG_OBJECT (dec, "Cannot handle version %i.", version);
return FALSE;
could_not_open:
GST_DEBUG_OBJECT (dec, "Could not open library '%s'.", path);
GST_DEBUG_OBJECT (dec, "Could not open library '%s': %s", path,
g_module_error ());
return FALSE;
could_not_load:
dlclose (handle);
GST_DEBUG_OBJECT (dec, "Could not load all symbols.");
g_module_close (module);
GST_DEBUG_OBJECT (dec, "Could not load all symbols: %s", g_module_error ());
return FALSE;
could_not_initialize:
if (context) {
funcs.RACloseCodec (context);
funcs.RAFreeDecoder (context);
}
dlclose (handle);
g_module_close (module);
GST_DEBUG_OBJECT (dec, "Initialization of REAL driver failed (%i).", res);
return FALSE;
could_not_set_caps:
@ -317,7 +330,7 @@ could_not_set_caps:
funcs.RACloseCodec (context);
funcs.RAFreeDecoder (context);
}
dlclose (handle);
g_module_close (module);
GST_DEBUG_OBJECT (dec, "Could not convince peer to accept caps.");
return FALSE;
}
@ -377,9 +390,9 @@ gst_real_audio_dec_finalize (GObject * object)
/* dec->funcs.RAFreeDecoder (dec->context); */
dec->context = NULL;
}
if (dec->handle) {
dlclose (dec->handle);
dec->handle = NULL;
if (dec->module) {
g_module_close (dec->module);
dec->module = NULL;
}
if (dec->path_racook) {

View file

@ -25,6 +25,7 @@
#include <gst/audio/audio.h>
G_BEGIN_DECLS
#define GST_TYPE_REAL_AUDIO_DEC (gst_real_audio_dec_get_type())
#define GST_REAL_AUDIO_DEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_REAL_AUDIO_DEC,GstRealAudioDec))
#define GST_REAL_AUDIO_DEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_REAL_AUDIO_DEC,GstRealAudioDecClass))
@ -32,9 +33,8 @@ G_BEGIN_DECLS
typedef struct _GstRealAudioDec GstRealAudioDec;
typedef struct _GstRealAudioDecClass GstRealAudioDecClass;
GType
gst_real_audio_dec_get_type (void)
G_GNUC_CONST;
GType gst_real_audio_dec_get_type (void);
G_END_DECLS
#endif /* __GST_REAL_AUDIO_DEC_H__ */

View file

@ -1,7 +1,7 @@
/* RealVideo wrapper plugin
*
* Copyright (C) 2005 Lutz Mueller <lutz@topfrose.de>
* 2006 Edward Hervey <bilboed@bilboed.com>
* Copyright (C) 2006 Edward Hervey <bilboed@bilboed.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -25,7 +25,6 @@
#include "gstrealvideodec.h"
#include <dlfcn.h>
#include <string.h>
GST_DEBUG_CATEGORY_STATIC (realvideode_debug);
@ -626,6 +625,8 @@ static gboolean
open_library (GstRealVideoDec * dec, GstRealVideoDecHooks * hooks,
GstRealVideoDecVersion version)
{
gpointer rv_custom_msg, rv_free, rv_init, rv_transform;
GModule *module;
gchar *path = NULL;
GST_DEBUG_OBJECT (dec,
@ -677,29 +678,34 @@ open_library (GstRealVideoDec * dec, GstRealVideoDecHooks * hooks,
goto unknown_version;
}
hooks->handle = dlopen (path, RTLD_LAZY);
if (!hooks->handle)
GST_LOG_OBJECT (dec, "Trying to open '%s'", path);
hooks->module = g_module_open (path, G_MODULE_BIND_LAZY);
if (hooks->module == NULL)
goto could_not_open;
/* First try opening legacy symbols */
hooks->custom_message = dlsym (hooks->handle, "RV20toYUV420CustomMessage");
hooks->free = dlsym (hooks->handle, "RV20toYUV420Free");
hooks->init = dlsym (hooks->handle, "RV20toYUV420Init");
hooks->transform = dlsym (hooks->handle, "RV20toYUV420Transform");
module = hooks->module;
if (!(hooks->custom_message && hooks->free && hooks->init
&& hooks->transform)) {
/* Else try loading new symbols */
hooks->custom_message = dlsym (hooks->handle, "RV40toYUV420CustomMessage");
hooks->free = dlsym (hooks->handle, "RV40toYUV420Free");
hooks->init = dlsym (hooks->handle, "RV40toYUV420Init");
hooks->transform = dlsym (hooks->handle, "RV40toYUV420Transform");
if (!(hooks->custom_message && hooks->free && hooks->init
&& hooks->transform))
goto could_not_load;
/* First try opening legacy symbols, if that fails try loading new symbols */
if (g_module_symbol (module, "RV20toYUV420Init", &rv_init) &&
g_module_symbol (module, "RV20toYUV420Free", &rv_free) &&
g_module_symbol (module, "RV20toYUV420Transform", &rv_transform) &&
g_module_symbol (module, "RV20toYUV420CustomMessage", &rv_custom_msg)) {
GST_LOG_OBJECT (dec, "Loaded legacy symbols");
} else if (g_module_symbol (module, "RV40toYUV420Init", &rv_init) &&
g_module_symbol (module, "RV40toYUV420Free", &rv_free) &&
g_module_symbol (module, "RV40toYUV420Transform", &rv_transform) &&
g_module_symbol (module, "RV40toYUV420CustomMessage", &rv_custom_msg)) {
GST_LOG_OBJECT (dec, "Loaded new symbols");
} else {
goto could_not_load;
}
hooks->init = rv_init;
hooks->free = rv_free;
hooks->transform = rv_transform;
hooks->custom_message = rv_custom_msg;
return TRUE;
no_known_libraries:
@ -718,14 +724,15 @@ unknown_version:
could_not_open:
{
GST_ERROR_OBJECT (dec, "Could not open library '%s'.", path);
GST_ERROR_OBJECT (dec, "Could not open library '%s':%s", path,
g_module_error ());
return FALSE;
}
could_not_load:
{
close_library (*hooks);
GST_ERROR_OBJECT (dec, "Could not load all symbols.");
GST_ERROR_OBJECT (dec, "Could not load all symbols: %s", g_module_error ());
return FALSE;
}
}
@ -736,8 +743,10 @@ close_library (GstRealVideoDecHooks hooks)
if (hooks.context && hooks.free)
hooks.free (hooks.context);
if (hooks.handle)
dlclose (hooks.handle);
if (hooks.module) {
g_module_close (hooks.module);
hooks.module = NULL;
}
}
static void

View file

@ -1,7 +1,7 @@
/* GStreamer
*
* Copyright (C) 2006 Lutz Mueller <lutz@topfrose.de>
* 2006 Edward Hervey <bilboed@bilbod.com>
* Copyright (C) 2006 Edward Hervey <bilboed@bilbod.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -43,7 +43,7 @@ enum _GstRealVideoDecVersion
};
typedef struct {
gpointer handle;
GModule *module;
guint32 (*custom_message) (gpointer, gpointer);
guint32 (*free) (gpointer);
@ -91,4 +91,7 @@ struct _GstRealVideoDecClass
GType gst_real_video_dec_get_type (void);
G_END_DECLS
#endif /* __GST_REAL_VIDEO_DEC_H__ */