From 2a3785b2ef39ee62a6d12f7a4fc62078fa2282d6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 16 Feb 2007 11:48:15 +0000 Subject: [PATCH] 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. --- ChangeLog | 20 ++++++++++++++++++++ ext/ffmpeg/gstffmpegdec.c | 25 ++++++++----------------- ext/ffmpeg/gstffmpegdemux.c | 36 +++++++++++++----------------------- ext/ffmpeg/gstffmpegenc.c | 29 +++++++++-------------------- ext/ffmpeg/gstffmpegmux.c | 27 +++++++++------------------ 5 files changed, 59 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index c20453b..27f9f2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2007-02-16 Tim-Philipp Müller + + * 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 * ext/ffmpeg/gstffmpegcfg.c: (gst_ffmpeg_flags_get_type): diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index 160c81e..a6b6dec 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -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; } diff --git a/ext/ffmpeg/gstffmpegdemux.c b/ext/ffmpeg/gstffmpegdemux.c index 2fc78fd..fd18b9c 100644 --- a/ext/ffmpeg/gstffmpegdemux.c +++ b/ext/ffmpeg/gstffmpegdemux.c @@ -33,7 +33,6 @@ #include #include #endif - #include #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; } diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 58563a5..6e6d6f5 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -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; } diff --git a/ext/ffmpeg/gstffmpegmux.c b/ext/ffmpeg/gstffmpegmux.c index 7f6ea26..94de5a8 100644 --- a/ext/ffmpeg/gstffmpegmux.c +++ b/ext/ffmpeg/gstffmpegmux.c @@ -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; } -- 2.7.4