ext/ffmpeg/: Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this can break horribly if sizeof(GType) happ...

Original commit message from CVS:
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_base_init),
(gst_ffmpegdec_register):
* ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init),
(gst_ffmpegdemux_register):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_base_init),
(gst_ffmpegenc_register):
* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init),
(gst_ffmpegmux_register):
Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this
can break horribly if sizeof(GType) happens to be bigger than
sizeof(int), because GPOINTER_TO_INT might then chop off some bits
of our GType (the reason this seems to works nevertheless is the
put-current-type-also-as-value-0-into-the-hash-table-as-fallback
hack used in the current code).
In any case, instead of just fixing this, let's not use a hash table
with GTypes here at all. g_type_{set|get}_qdata() seems to do the
job just as well.
This commit is contained in:
Tim-Philipp Müller 2007-02-16 11:48:15 +00:00
parent 5c81998eb6
commit 2a3785b2ef
5 changed files with 59 additions and 78 deletions

View file

@ -1,3 +1,23 @@
2007-02-16 Tim-Philipp Müller <tim at centricular dot net>
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_base_init),
(gst_ffmpegdec_register):
* ext/ffmpeg/gstffmpegdemux.c: (gst_ffmpegdemux_base_init),
(gst_ffmpegdemux_register):
* ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_base_init),
(gst_ffmpegenc_register):
* ext/ffmpeg/gstffmpegmux.c: (gst_ffmpegmux_base_init),
(gst_ffmpegmux_register):
Don't use GINT_TO_POINTER and GPOINTER_TO_INT with GTypes, this
can break horribly if sizeof(GType) happens to be bigger than
sizeof(int), because GPOINTER_TO_INT might then chop off some bits
of our GType (the reason this seems to works nevertheless is the
put-current-type-also-as-value-0-into-the-hash-table-as-fallback
hack used in the current code).
In any case, instead of just fixing this, let's not use a hash table
with GTypes here at all. g_type_{set|get}_qdata() seems to do the
job just as well.
2007-02-14 Edward Hervey <edward@fluendo.com>
* ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_flags_get_type):

View file

@ -126,9 +126,7 @@ enum
ARG_SKIPFRAME
};
static GHashTable *global_plugins;
/* A number of functon prototypes are given so we can refer to them later. */
/* A number of function prototypes are given so we can refer to them later. */
static void gst_ffmpegdec_base_init (GstFFMpegDecClass * klass);
static void gst_ffmpegdec_class_init (GstFFMpegDecClass * klass);
static void gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec);
@ -157,6 +155,8 @@ static int gst_ffmpegdec_get_buffer (AVCodecContext * context,
static void gst_ffmpegdec_release_buffer (AVCodecContext * context,
AVFrame * picture);
#define GST_FFDEC_PARAMS_QDATA g_quark_from_static_string("ffdec-params")
static GstElementClass *parent_class = NULL;
#define GST_FFMPEGDEC_TYPE_LOWRES (gst_ffmpegdec_lowres_get_type())
@ -205,17 +205,15 @@ gst_ffmpegdec_skipframe_get_type (void)
static void
gst_ffmpegdec_base_init (GstFFMpegDecClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstFFMpegDecClassParams *params;
GstElementDetails details;
GstPadTemplate *sinktempl, *srctempl;
params = g_hash_table_lookup (global_plugins,
GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
if (!params)
params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
g_assert (params);
params =
(GstFFMpegDecClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
GST_FFDEC_PARAMS_QDATA);
g_assert (params != NULL);
/* construct the element details struct */
details.longname = g_strdup_printf ("FFMPEG %s decoder",
@ -2109,8 +2107,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
in_plugin = first_avcodec;
global_plugins = g_hash_table_new (NULL, NULL);
while (in_plugin) {
GstFFMpegDecClassParams *params;
GstCaps *srccaps = NULL, *sinkcaps = NULL;
@ -2158,11 +2154,10 @@ gst_ffmpegdec_register (GstPlugin * plugin)
params->in_plugin = in_plugin;
params->srccaps = gst_caps_ref (srccaps);
params->sinkcaps = gst_caps_ref (sinkcaps);
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (0), (gpointer) params);
/* create the gtype now */
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
g_type_set_qdata (type, GST_FFDEC_PARAMS_QDATA, (gpointer) params);
/* (Ronald) MPEG-4 gets a higher priority because it has been well-
* tested and by far outperforms divxdec/xviddec - so we prefer it.
@ -2201,9 +2196,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
g_free (type_name);
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (type), (gpointer) params);
next:
if (sinkcaps)
gst_caps_unref (sinkcaps);
@ -2211,7 +2203,6 @@ gst_ffmpegdec_register (GstPlugin * plugin)
gst_caps_unref (srccaps);
in_plugin = in_plugin->next;
}
g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
return TRUE;
}

View file

@ -33,7 +33,6 @@
#include <ffmpeg/avformat.h>
#include <ffmpeg/avi.h>
#endif
#include <gst/gst.h>
#include "gstffmpeg.h"
@ -102,9 +101,7 @@ struct _GstFFMpegDemuxClass
GstPadTemplate *audiosrctempl;
};
static GHashTable *global_plugins;
/* A number of functon prototypes are given so we can refer to them later. */
/* A number of function prototypes are given so we can refer to them later. */
static void gst_ffmpegdemux_class_init (GstFFMpegDemuxClass * klass);
static void gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass);
static void gst_ffmpegdemux_init (GstFFMpegDemux * demux);
@ -127,6 +124,8 @@ gst_ffmpegdemux_send_event (GstElement * element, GstEvent * event);
static GstStateChangeReturn
gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition);
#define GST_FFDEMUX_PARAMS_QDATA g_quark_from_static_string("ffdemux-params")
static GstElementClass *parent_class = NULL;
static const gchar *
@ -167,17 +166,15 @@ gst_ffmpegdemux_averror (gint av_errno)
static void
gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstFFMpegDemuxClassParams *params;
GstElementDetails details;
GstPadTemplate *sinktempl, *audiosrctempl, *videosrctempl;
params = g_hash_table_lookup (global_plugins,
GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
if (!params)
params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
g_assert (params);
params =
(GstFFMpegDemuxClassParams *)
g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_FFDEMUX_PARAMS_QDATA);
g_assert (params != NULL);
/* construct the element details struct */
details.longname = g_strdup_printf ("FFMPEG %s demuxer",
@ -512,6 +509,7 @@ gst_ffmpegdemux_perform_seek (GstFFMpegDemux * demux, GstEvent * event)
/* and prepare to continue streaming */
if (flush) {
gint n;
/* send flush stop, peer will accept data and events again. We
* are not yet providing data as we still have the STREAM_LOCK. */
gst_ffmpegdemux_push_event (demux, gst_event_new_flush_stop ());
@ -1234,7 +1232,7 @@ gst_ffmpegdemux_loop (GstPad * pad)
/* if a pad is in e.g. WRONG_STATE, we want to pause to unlock the STREAM_LOCK */
if ((ret != GST_FLOW_OK)
&& ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)) {
&& ((ret = gst_ffmpegdemux_aggregated_flow (demux)) != GST_FLOW_OK)) {
GST_WARNING_OBJECT (demux, "stream_movi flow: %s / %s",
gst_flow_get_name (stream->last_flow), gst_flow_get_name (ret));
goto pause;
@ -1433,8 +1431,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
in_plugin = first_iformat;
global_plugins = g_hash_table_new (NULL, NULL);
while (in_plugin) {
gchar *type_name, *typefind_name;
gchar *p, *name = NULL;
@ -1506,9 +1502,9 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
!strcmp (in_plugin->name, "ea") ||
!strcmp (in_plugin->name, "daud") ||
!strcmp (in_plugin->name, "avs") ||
!strcmp (in_plugin->name, "aiff") ||
!strcmp (in_plugin->name, "4xm") ||
!strcmp(in_plugin->name, "yuv4mpegpipe"))
!strcmp (in_plugin->name, "aiff") ||
!strcmp (in_plugin->name, "4xm") ||
!strcmp (in_plugin->name, "yuv4mpegpipe"))
rank = GST_RANK_MARGINAL;
else
rank = GST_RANK_NONE;
@ -1551,14 +1547,9 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
params->videosrccaps = videosrccaps;
params->audiosrccaps = audiosrccaps;
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (0), (gpointer) params);
/* create the type now */
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (type), (gpointer) params);
g_type_set_qdata (type, GST_FFDEMUX_PARAMS_QDATA, (gpointer) params);
if (in_plugin->extensions)
extensions = g_strsplit (in_plugin->extensions, " ", 0);
@ -1585,7 +1576,6 @@ gst_ffmpegdemux_register (GstPlugin * plugin)
g_free (name);
in_plugin = in_plugin->next;
}
g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
return TRUE;
}

View file

@ -89,9 +89,7 @@ gst_ffmpegenc_me_method_get_type (void)
return ffmpegenc_me_method_type;
}
static GHashTable *enc_global_plugins;
/* A number of functon prototypes are given so we can refer to them later. */
/* A number of function prototypes are given so we can refer to them later. */
static void gst_ffmpegenc_class_init (GstFFMpegEncClass * klass);
static void gst_ffmpegenc_base_init (GstFFMpegEncClass * klass);
static void gst_ffmpegenc_init (GstFFMpegEnc * ffmpegenc);
@ -113,6 +111,8 @@ static void gst_ffmpegenc_get_property (GObject * object,
static GstStateChangeReturn gst_ffmpegenc_change_state (GstElement * element,
GstStateChange transition);
#define GST_FFENC_PARAMS_QDATA g_quark_from_static_string("ffenc-params")
static GstElementClass *parent_class = NULL;
/*static guint gst_ffmpegenc_signals[LAST_SIGNAL] = { 0 }; */
@ -120,19 +120,15 @@ static GstElementClass *parent_class = NULL;
static void
gst_ffmpegenc_base_init (GstFFMpegEncClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
GstFFMpegEncClassParams *params;
GstElementDetails details;
GstPadTemplate *srctempl, *sinktempl;
params = g_hash_table_lookup (enc_global_plugins,
GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
/* HACK: if we don't have a GType yet, our params are stored at position 0 */
if (!params) {
params = g_hash_table_lookup (enc_global_plugins, GINT_TO_POINTER (0));
}
g_assert (params);
params =
(GstFFMpegEncClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
GST_FFENC_PARAMS_QDATA);
g_assert (params != NULL);
/* construct the element details struct */
details.longname = g_strdup_printf ("FFMPEG %s encoder",
@ -928,8 +924,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
in_plugin = first_avcodec;
enc_global_plugins = g_hash_table_new (NULL, NULL);
/* build global ffmpeg param/property info */
gst_ffmpeg_cfg_init ();
@ -983,11 +977,10 @@ gst_ffmpegenc_register (GstPlugin * plugin)
params->srccaps = gst_caps_ref (srccaps);
params->sinkcaps = gst_caps_ref (sinkcaps);
g_hash_table_insert (enc_global_plugins,
GINT_TO_POINTER (0), (gpointer) params);
/* create the glib type now */
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
g_type_set_qdata (type, GST_FFENC_PARAMS_QDATA, (gpointer) params);
if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
g_free (type_name);
return FALSE;
@ -995,9 +988,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
g_free (type_name);
g_hash_table_insert (enc_global_plugins,
GINT_TO_POINTER (type), (gpointer) params);
next:
if (sinkcaps)
gst_caps_unref (sinkcaps);
@ -1005,7 +995,6 @@ gst_ffmpegenc_register (GstPlugin * plugin)
gst_caps_unref (srccaps);
in_plugin = in_plugin->next;
}
g_hash_table_remove (enc_global_plugins, GINT_TO_POINTER (0));
return TRUE;
}

View file

@ -102,9 +102,7 @@ enum
/* FILL ME */
};
static GHashTable *global_plugins;
/* A number of functon prototypes are given so we can refer to them later. */
/* A number of function prototypes are given so we can refer to them later. */
static void gst_ffmpegmux_class_init (GstFFMpegMuxClass * klass);
static void gst_ffmpegmux_base_init (gpointer g_class);
static void gst_ffmpegmux_init (GstFFMpegMux * ffmpegmux,
@ -122,6 +120,8 @@ static gboolean gst_ffmpegmux_sink_event (GstPad * pad, GstEvent * event);
static GstStateChangeReturn gst_ffmpegmux_change_state (GstElement * element,
GstStateChange transition);
#define GST_FFMUX_PARAMS_QDATA g_quark_from_static_string("ffmux-params")
static GstElementClass *parent_class = NULL;
/*static guint gst_ffmpegmux_signals[LAST_SIGNAL] = { 0 }; */
@ -129,18 +129,16 @@ static GstElementClass *parent_class = NULL;
static void
gst_ffmpegmux_base_init (gpointer g_class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
GstFFMpegMuxClass *klass = (GstFFMpegMuxClass *) g_class;
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GstElementDetails details;
GstFFMpegMuxClassParams *params;
GstPadTemplate *videosinktempl, *audiosinktempl, *srctempl;
params = g_hash_table_lookup (global_plugins,
GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
if (!params)
params = g_hash_table_lookup (global_plugins, GINT_TO_POINTER (0));
g_assert (params);
params =
(GstFFMpegMuxClassParams *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass),
GST_FFMUX_PARAMS_QDATA);
g_assert (params != NULL);
/* construct the element details struct */
details.longname = g_strdup_printf ("FFMPEG %s Muxer",
@ -675,8 +673,6 @@ gst_ffmpegmux_register (GstPlugin * plugin)
in_plugin = first_oformat;
global_plugins = g_hash_table_new (NULL, NULL);
while (in_plugin) {
gchar *type_name;
gchar *p;
@ -732,12 +728,11 @@ gst_ffmpegmux_register (GstPlugin * plugin)
params->videosinkcaps = videosinkcaps;
params->audiosinkcaps = audiosinkcaps;
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (0), (gpointer) params);
/* create the type now */
type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
g_type_set_qdata (type, GST_FFMUX_PARAMS_QDATA, (gpointer) params);
g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
if (!gst_element_register (plugin, type_name, GST_RANK_NONE, type)) {
g_free (type_name);
gst_caps_unref (srccaps);
@ -750,13 +745,9 @@ gst_ffmpegmux_register (GstPlugin * plugin)
g_free (type_name);
g_hash_table_insert (global_plugins,
GINT_TO_POINTER (type), (gpointer) params);
next:
in_plugin = in_plugin->next;
}
g_hash_table_remove (global_plugins, GINT_TO_POINTER (0));
return TRUE;
}